dispatch.c revision 171577
1/* 2 * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1999-2003 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and 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: dispatch.c,v 1.116.18.13.10.4 2007/06/27 04:17:45 marka Exp $ */ 19 20/*! \file */ 21 22#include <config.h> 23 24#include <stdlib.h> 25#include <sys/types.h> 26#include <unistd.h> 27 28#include <isc/entropy.h> 29#include <isc/mem.h> 30#include <isc/mutex.h> 31#include <isc/print.h> 32#include <isc/string.h> 33#include <isc/task.h> 34#include <isc/time.h> 35#include <isc/util.h> 36 37#include <dns/acl.h> 38#include <dns/dispatch.h> 39#include <dns/events.h> 40#include <dns/log.h> 41#include <dns/message.h> 42#include <dns/portlist.h> 43#include <dns/tcpmsg.h> 44#include <dns/types.h> 45 46typedef ISC_LIST(dns_dispentry_t) dns_displist_t; 47 48typedef struct dns_nsid { 49 isc_uint16_t nsid_state; 50 isc_uint16_t *nsid_vtable; 51 isc_uint16_t *nsid_pool; 52 isc_uint16_t nsid_a1, nsid_a2, nsid_a3; 53 isc_uint16_t nsid_c1, nsid_c2, nsid_c3; 54 isc_uint16_t nsid_state2; 55 isc_boolean_t nsid_usepool; 56} dns_nsid_t; 57 58typedef struct dns_qid { 59 unsigned int magic; 60 unsigned int qid_nbuckets; /*%< hash table size */ 61 unsigned int qid_increment; /*%< id increment on collision */ 62 isc_mutex_t lock; 63 dns_nsid_t nsid; 64 dns_displist_t *qid_table; /*%< the table itself */ 65} dns_qid_t; 66 67struct dns_dispatchmgr { 68 /* Unlocked. */ 69 unsigned int magic; 70 isc_mem_t *mctx; 71 dns_acl_t *blackhole; 72 dns_portlist_t *portlist; 73 74 /* Locked by "lock". */ 75 isc_mutex_t lock; 76 unsigned int state; 77 ISC_LIST(dns_dispatch_t) list; 78 79 /* locked by buffer lock */ 80 dns_qid_t *qid; 81 isc_mutex_t buffer_lock; 82 unsigned int buffers; /*%< allocated buffers */ 83 unsigned int buffersize; /*%< size of each buffer */ 84 unsigned int maxbuffers; /*%< max buffers */ 85 86 /* Locked internally. */ 87 isc_mutex_t pool_lock; 88 isc_mempool_t *epool; /*%< memory pool for events */ 89 isc_mempool_t *rpool; /*%< memory pool for replies */ 90 isc_mempool_t *dpool; /*%< dispatch allocations */ 91 isc_mempool_t *bpool; /*%< memory pool for buffers */ 92 93 isc_entropy_t *entropy; /*%< entropy source */ 94}; 95 96#define MGR_SHUTTINGDOWN 0x00000001U 97#define MGR_IS_SHUTTINGDOWN(l) (((l)->state & MGR_SHUTTINGDOWN) != 0) 98 99#define IS_PRIVATE(d) (((d)->attributes & DNS_DISPATCHATTR_PRIVATE) != 0) 100 101struct dns_dispentry { 102 unsigned int magic; 103 dns_dispatch_t *disp; 104 dns_messageid_t id; 105 unsigned int bucket; 106 isc_sockaddr_t host; 107 isc_task_t *task; 108 isc_taskaction_t action; 109 void *arg; 110 isc_boolean_t item_out; 111 ISC_LIST(dns_dispatchevent_t) items; 112 ISC_LINK(dns_dispentry_t) link; 113}; 114 115#define INVALID_BUCKET (0xffffdead) 116 117struct dns_dispatch { 118 /* Unlocked. */ 119 unsigned int magic; /*%< magic */ 120 dns_dispatchmgr_t *mgr; /*%< dispatch manager */ 121 isc_task_t *task; /*%< internal task */ 122 isc_socket_t *socket; /*%< isc socket attached to */ 123 isc_sockaddr_t local; /*%< local address */ 124 unsigned int maxrequests; /*%< max requests */ 125 isc_event_t *ctlevent; 126 127 /*% Locked by mgr->lock. */ 128 ISC_LINK(dns_dispatch_t) link; 129 130 /* Locked by "lock". */ 131 isc_mutex_t lock; /*%< locks all below */ 132 isc_sockettype_t socktype; 133 unsigned int attributes; 134 unsigned int refcount; /*%< number of users */ 135 dns_dispatchevent_t *failsafe_ev; /*%< failsafe cancel event */ 136 unsigned int shutting_down : 1, 137 shutdown_out : 1, 138 connected : 1, 139 tcpmsg_valid : 1, 140 recv_pending : 1; /*%< is a recv() pending? */ 141 isc_result_t shutdown_why; 142 unsigned int requests; /*%< how many requests we have */ 143 unsigned int tcpbuffers; /*%< allocated buffers */ 144 dns_tcpmsg_t tcpmsg; /*%< for tcp streams */ 145 dns_qid_t *qid; 146}; 147 148#define QID_MAGIC ISC_MAGIC('Q', 'i', 'd', ' ') 149#define VALID_QID(e) ISC_MAGIC_VALID((e), QID_MAGIC) 150 151#define RESPONSE_MAGIC ISC_MAGIC('D', 'r', 's', 'p') 152#define VALID_RESPONSE(e) ISC_MAGIC_VALID((e), RESPONSE_MAGIC) 153 154#define DISPATCH_MAGIC ISC_MAGIC('D', 'i', 's', 'p') 155#define VALID_DISPATCH(e) ISC_MAGIC_VALID((e), DISPATCH_MAGIC) 156 157#define DNS_DISPATCHMGR_MAGIC ISC_MAGIC('D', 'M', 'g', 'r') 158#define VALID_DISPATCHMGR(e) ISC_MAGIC_VALID((e), DNS_DISPATCHMGR_MAGIC) 159 160#define DNS_QID(disp) ((disp)->socktype == isc_sockettype_tcp) ? \ 161 (disp)->qid : (disp)->mgr->qid 162/* 163 * Statics. 164 */ 165static dns_dispentry_t *bucket_search(dns_qid_t *, isc_sockaddr_t *, 166 dns_messageid_t, unsigned int); 167static isc_boolean_t destroy_disp_ok(dns_dispatch_t *); 168static void destroy_disp(isc_task_t *task, isc_event_t *event); 169static void udp_recv(isc_task_t *, isc_event_t *); 170static void tcp_recv(isc_task_t *, isc_event_t *); 171static void startrecv(dns_dispatch_t *); 172static dns_messageid_t dns_randomid(dns_nsid_t *); 173static isc_uint32_t dns_hash(dns_qid_t *, isc_sockaddr_t *, dns_messageid_t); 174static void free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len); 175static void *allocate_udp_buffer(dns_dispatch_t *disp); 176static inline void free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev); 177static inline dns_dispatchevent_t *allocate_event(dns_dispatch_t *disp); 178static void do_cancel(dns_dispatch_t *disp); 179static dns_dispentry_t *linear_first(dns_qid_t *disp); 180static dns_dispentry_t *linear_next(dns_qid_t *disp, 181 dns_dispentry_t *resp); 182static void dispatch_free(dns_dispatch_t **dispp); 183static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr, 184 isc_socketmgr_t *sockmgr, 185 isc_taskmgr_t *taskmgr, 186 isc_sockaddr_t *localaddr, 187 unsigned int maxrequests, 188 unsigned int attributes, 189 dns_dispatch_t **dispp); 190static isc_boolean_t destroy_mgr_ok(dns_dispatchmgr_t *mgr); 191static void destroy_mgr(dns_dispatchmgr_t **mgrp); 192static isc_result_t qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets, 193 unsigned int increment, isc_boolean_t usepool, 194 dns_qid_t **qidp); 195static void qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp); 196static isc_uint16_t nsid_next(dns_nsid_t *nsid); 197static isc_result_t nsid_init(isc_mem_t *mctx, dns_nsid_t *nsid, isc_boolean_t usepool); 198static void nsid_destroy(isc_mem_t *mctx, dns_nsid_t *nsid); 199 200#define LVL(x) ISC_LOG_DEBUG(x) 201 202static void 203mgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...) 204 ISC_FORMAT_PRINTF(3, 4); 205 206static void 207mgr_log(dns_dispatchmgr_t *mgr, int level, const char *fmt, ...) { 208 char msgbuf[2048]; 209 va_list ap; 210 211 if (! isc_log_wouldlog(dns_lctx, level)) 212 return; 213 214 va_start(ap, fmt); 215 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); 216 va_end(ap); 217 218 isc_log_write(dns_lctx, 219 DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH, 220 level, "dispatchmgr %p: %s", mgr, msgbuf); 221} 222 223static void 224dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...) 225 ISC_FORMAT_PRINTF(3, 4); 226 227static void 228dispatch_log(dns_dispatch_t *disp, int level, const char *fmt, ...) { 229 char msgbuf[2048]; 230 va_list ap; 231 232 if (! isc_log_wouldlog(dns_lctx, level)) 233 return; 234 235 va_start(ap, fmt); 236 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); 237 va_end(ap); 238 239 isc_log_write(dns_lctx, 240 DNS_LOGCATEGORY_DISPATCH, DNS_LOGMODULE_DISPATCH, 241 level, "dispatch %p: %s", disp, msgbuf); 242} 243 244static void 245request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, 246 int level, const char *fmt, ...) 247 ISC_FORMAT_PRINTF(4, 5); 248 249static void 250request_log(dns_dispatch_t *disp, dns_dispentry_t *resp, 251 int level, const char *fmt, ...) 252{ 253 char msgbuf[2048]; 254 char peerbuf[256]; 255 va_list ap; 256 257 if (! isc_log_wouldlog(dns_lctx, level)) 258 return; 259 260 va_start(ap, fmt); 261 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); 262 va_end(ap); 263 264 if (VALID_RESPONSE(resp)) { 265 isc_sockaddr_format(&resp->host, peerbuf, sizeof(peerbuf)); 266 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH, 267 DNS_LOGMODULE_DISPATCH, level, 268 "dispatch %p response %p %s: %s", disp, resp, 269 peerbuf, msgbuf); 270 } else { 271 isc_log_write(dns_lctx, DNS_LOGCATEGORY_DISPATCH, 272 DNS_LOGMODULE_DISPATCH, level, 273 "dispatch %p req/resp %p: %s", disp, resp, 274 msgbuf); 275 } 276} 277 278/* 279 * Return an unpredictable message ID. 280 */ 281static dns_messageid_t 282dns_randomid(dns_nsid_t *nsid) { 283 isc_uint32_t id; 284 285 id = nsid_next(nsid); 286 287 return ((dns_messageid_t)id); 288} 289 290/* 291 * Return a hash of the destination and message id. 292 */ 293static isc_uint32_t 294dns_hash(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id) { 295 unsigned int ret; 296 297 ret = isc_sockaddr_hash(dest, ISC_TRUE); 298 ret ^= id; 299 ret %= qid->qid_nbuckets; 300 301 INSIST(ret < qid->qid_nbuckets); 302 303 return (ret); 304} 305 306/* 307 * Find the first entry in 'qid'. Returns NULL if there are no entries. 308 */ 309static dns_dispentry_t * 310linear_first(dns_qid_t *qid) { 311 dns_dispentry_t *ret; 312 unsigned int bucket; 313 314 bucket = 0; 315 316 while (bucket < qid->qid_nbuckets) { 317 ret = ISC_LIST_HEAD(qid->qid_table[bucket]); 318 if (ret != NULL) 319 return (ret); 320 bucket++; 321 } 322 323 return (NULL); 324} 325 326/* 327 * Find the next entry after 'resp' in 'qid'. Return NULL if there are 328 * no more entries. 329 */ 330static dns_dispentry_t * 331linear_next(dns_qid_t *qid, dns_dispentry_t *resp) { 332 dns_dispentry_t *ret; 333 unsigned int bucket; 334 335 ret = ISC_LIST_NEXT(resp, link); 336 if (ret != NULL) 337 return (ret); 338 339 bucket = resp->bucket; 340 bucket++; 341 while (bucket < qid->qid_nbuckets) { 342 ret = ISC_LIST_HEAD(qid->qid_table[bucket]); 343 if (ret != NULL) 344 return (ret); 345 bucket++; 346 } 347 348 return (NULL); 349} 350 351/* 352 * The dispatch must be locked. 353 */ 354static isc_boolean_t 355destroy_disp_ok(dns_dispatch_t *disp) 356{ 357 if (disp->refcount != 0) 358 return (ISC_FALSE); 359 360 if (disp->recv_pending != 0) 361 return (ISC_FALSE); 362 363 if (disp->shutting_down == 0) 364 return (ISC_FALSE); 365 366 return (ISC_TRUE); 367} 368 369 370/* 371 * Called when refcount reaches 0 (and safe to destroy). 372 * 373 * The dispatcher must not be locked. 374 * The manager must be locked. 375 */ 376static void 377destroy_disp(isc_task_t *task, isc_event_t *event) { 378 dns_dispatch_t *disp; 379 dns_dispatchmgr_t *mgr; 380 isc_boolean_t killmgr; 381 382 INSIST(event->ev_type == DNS_EVENT_DISPATCHCONTROL); 383 384 UNUSED(task); 385 386 disp = event->ev_arg; 387 mgr = disp->mgr; 388 389 LOCK(&mgr->lock); 390 ISC_LIST_UNLINK(mgr->list, disp, link); 391 392 dispatch_log(disp, LVL(90), 393 "shutting down; detaching from sock %p, task %p", 394 disp->socket, disp->task); 395 396 isc_socket_detach(&disp->socket); 397 isc_task_detach(&disp->task); 398 isc_event_free(&event); 399 400 dispatch_free(&disp); 401 402 killmgr = destroy_mgr_ok(mgr); 403 UNLOCK(&mgr->lock); 404 if (killmgr) 405 destroy_mgr(&mgr); 406} 407 408 409/* 410 * Find an entry for query ID 'id' and socket address 'dest' in 'qid'. 411 * Return NULL if no such entry exists. 412 */ 413static dns_dispentry_t * 414bucket_search(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id, 415 unsigned int bucket) 416{ 417 dns_dispentry_t *res; 418 419 REQUIRE(bucket < qid->qid_nbuckets); 420 421 res = ISC_LIST_HEAD(qid->qid_table[bucket]); 422 423 while (res != NULL) { 424 if ((res->id == id) && isc_sockaddr_equal(dest, &res->host)) 425 return (res); 426 res = ISC_LIST_NEXT(res, link); 427 } 428 429 return (NULL); 430} 431 432static void 433free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) { 434 INSIST(buf != NULL && len != 0); 435 436 437 switch (disp->socktype) { 438 case isc_sockettype_tcp: 439 INSIST(disp->tcpbuffers > 0); 440 disp->tcpbuffers--; 441 isc_mem_put(disp->mgr->mctx, buf, len); 442 break; 443 case isc_sockettype_udp: 444 LOCK(&disp->mgr->buffer_lock); 445 INSIST(disp->mgr->buffers > 0); 446 INSIST(len == disp->mgr->buffersize); 447 disp->mgr->buffers--; 448 isc_mempool_put(disp->mgr->bpool, buf); 449 UNLOCK(&disp->mgr->buffer_lock); 450 break; 451 default: 452 INSIST(0); 453 break; 454 } 455} 456 457static void * 458allocate_udp_buffer(dns_dispatch_t *disp) { 459 void *temp; 460 461 LOCK(&disp->mgr->buffer_lock); 462 temp = isc_mempool_get(disp->mgr->bpool); 463 464 if (temp != NULL) 465 disp->mgr->buffers++; 466 UNLOCK(&disp->mgr->buffer_lock); 467 468 return (temp); 469} 470 471static inline void 472free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev) { 473 if (disp->failsafe_ev == ev) { 474 INSIST(disp->shutdown_out == 1); 475 disp->shutdown_out = 0; 476 477 return; 478 } 479 480 isc_mempool_put(disp->mgr->epool, ev); 481} 482 483static inline dns_dispatchevent_t * 484allocate_event(dns_dispatch_t *disp) { 485 dns_dispatchevent_t *ev; 486 487 ev = isc_mempool_get(disp->mgr->epool); 488 if (ev == NULL) 489 return (NULL); 490 ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0, 491 NULL, NULL, NULL, NULL, NULL); 492 493 return (ev); 494} 495 496/* 497 * General flow: 498 * 499 * If I/O result == CANCELED or error, free the buffer. 500 * 501 * If query, free the buffer, restart. 502 * 503 * If response: 504 * Allocate event, fill in details. 505 * If cannot allocate, free buffer, restart. 506 * find target. If not found, free buffer, restart. 507 * if event queue is not empty, queue. else, send. 508 * restart. 509 */ 510static void 511udp_recv(isc_task_t *task, isc_event_t *ev_in) { 512 isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; 513 dns_dispatch_t *disp = ev_in->ev_arg; 514 dns_messageid_t id; 515 isc_result_t dres; 516 isc_buffer_t source; 517 unsigned int flags; 518 dns_dispentry_t *resp; 519 dns_dispatchevent_t *rev; 520 unsigned int bucket; 521 isc_boolean_t killit; 522 isc_boolean_t queue_response; 523 dns_dispatchmgr_t *mgr; 524 dns_qid_t *qid; 525 isc_netaddr_t netaddr; 526 int match; 527 528 UNUSED(task); 529 530 LOCK(&disp->lock); 531 532 mgr = disp->mgr; 533 qid = mgr->qid; 534 535 dispatch_log(disp, LVL(90), 536 "got packet: requests %d, buffers %d, recvs %d", 537 disp->requests, disp->mgr->buffers, disp->recv_pending); 538 539 if (ev->ev_type == ISC_SOCKEVENT_RECVDONE) { 540 /* 541 * Unless the receive event was imported from a listening 542 * interface, in which case the event type is 543 * DNS_EVENT_IMPORTRECVDONE, receive operation must be pending. 544 */ 545 INSIST(disp->recv_pending != 0); 546 disp->recv_pending = 0; 547 } 548 549 if (disp->shutting_down) { 550 /* 551 * This dispatcher is shutting down. 552 */ 553 free_buffer(disp, ev->region.base, ev->region.length); 554 555 isc_event_free(&ev_in); 556 ev = NULL; 557 558 killit = destroy_disp_ok(disp); 559 UNLOCK(&disp->lock); 560 if (killit) 561 isc_task_send(disp->task, &disp->ctlevent); 562 563 return; 564 } 565 566 if (ev->result != ISC_R_SUCCESS) { 567 free_buffer(disp, ev->region.base, ev->region.length); 568 569 if (ev->result != ISC_R_CANCELED) 570 dispatch_log(disp, ISC_LOG_ERROR, 571 "odd socket result in udp_recv(): %s", 572 isc_result_totext(ev->result)); 573 574 UNLOCK(&disp->lock); 575 isc_event_free(&ev_in); 576 return; 577 } 578 579 /* 580 * If this is from a blackholed address, drop it. 581 */ 582 isc_netaddr_fromsockaddr(&netaddr, &ev->address); 583 if (disp->mgr->blackhole != NULL && 584 dns_acl_match(&netaddr, NULL, disp->mgr->blackhole, 585 NULL, &match, NULL) == ISC_R_SUCCESS && 586 match > 0) 587 { 588 if (isc_log_wouldlog(dns_lctx, LVL(10))) { 589 char netaddrstr[ISC_NETADDR_FORMATSIZE]; 590 isc_netaddr_format(&netaddr, netaddrstr, 591 sizeof(netaddrstr)); 592 dispatch_log(disp, LVL(10), 593 "blackholed packet from %s", 594 netaddrstr); 595 } 596 free_buffer(disp, ev->region.base, ev->region.length); 597 goto restart; 598 } 599 600 /* 601 * Peek into the buffer to see what we can see. 602 */ 603 isc_buffer_init(&source, ev->region.base, ev->region.length); 604 isc_buffer_add(&source, ev->n); 605 dres = dns_message_peekheader(&source, &id, &flags); 606 if (dres != ISC_R_SUCCESS) { 607 free_buffer(disp, ev->region.base, ev->region.length); 608 dispatch_log(disp, LVL(10), "got garbage packet"); 609 goto restart; 610 } 611 612 dispatch_log(disp, LVL(92), 613 "got valid DNS message header, /QR %c, id %u", 614 ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id); 615 616 /* 617 * Look at flags. If query, drop it. If response, 618 * look to see where it goes. 619 */ 620 queue_response = ISC_FALSE; 621 if ((flags & DNS_MESSAGEFLAG_QR) == 0) { 622 /* query */ 623 free_buffer(disp, ev->region.base, ev->region.length); 624 goto restart; 625 } 626 627 dns_dispatch_hash(&ev->timestamp, sizeof(&ev->timestamp)); 628 dns_dispatch_hash(ev->region.base, ev->region.length); 629 630 /* response */ 631 bucket = dns_hash(qid, &ev->address, id); 632 LOCK(&qid->lock); 633 resp = bucket_search(qid, &ev->address, id, bucket); 634 dispatch_log(disp, LVL(90), 635 "search for response in bucket %d: %s", 636 bucket, (resp == NULL ? "not found" : "found")); 637 638 if (resp == NULL) { 639 free_buffer(disp, ev->region.base, ev->region.length); 640 goto unlock; 641 } 642 643 /* 644 * Now that we have the original dispatch the query was sent 645 * from check that the address and port the response was 646 * sent to make sense. 647 */ 648 if (disp != resp->disp) { 649 isc_sockaddr_t a1; 650 isc_sockaddr_t a2; 651 652 /* 653 * Check that the socket types and ports match. 654 */ 655 if (disp->socktype != resp->disp->socktype || 656 isc_sockaddr_getport(&disp->local) != 657 isc_sockaddr_getport(&resp->disp->local)) { 658 free_buffer(disp, ev->region.base, ev->region.length); 659 goto unlock; 660 } 661 662 /* 663 * If both dispatches are bound to an address then fail as 664 * the addresses can't be equal (enforced by the IP stack). 665 * 666 * Note under Linux a packet can be sent out via IPv4 socket 667 * and the response be received via a IPv6 socket. 668 * 669 * Requests sent out via IPv6 should always come back in 670 * via IPv6. 671 */ 672 if (isc_sockaddr_pf(&resp->disp->local) == PF_INET6 && 673 isc_sockaddr_pf(&disp->local) != PF_INET6) { 674 free_buffer(disp, ev->region.base, ev->region.length); 675 goto unlock; 676 } 677 isc_sockaddr_anyofpf(&a1, isc_sockaddr_pf(&resp->disp->local)); 678 isc_sockaddr_anyofpf(&a2, isc_sockaddr_pf(&disp->local)); 679 if (!isc_sockaddr_eqaddr(&a1, &resp->disp->local) && 680 !isc_sockaddr_eqaddr(&a2, &disp->local)) { 681 free_buffer(disp, ev->region.base, ev->region.length); 682 goto unlock; 683 } 684 } 685 686 queue_response = resp->item_out; 687 rev = allocate_event(resp->disp); 688 if (rev == NULL) { 689 free_buffer(disp, ev->region.base, ev->region.length); 690 goto unlock; 691 } 692 693 /* 694 * At this point, rev contains the event we want to fill in, and 695 * resp contains the information on the place to send it to. 696 * Send the event off. 697 */ 698 isc_buffer_init(&rev->buffer, ev->region.base, ev->region.length); 699 isc_buffer_add(&rev->buffer, ev->n); 700 rev->result = ISC_R_SUCCESS; 701 rev->id = id; 702 rev->addr = ev->address; 703 rev->pktinfo = ev->pktinfo; 704 rev->attributes = ev->attributes; 705 if (queue_response) { 706 ISC_LIST_APPEND(resp->items, rev, ev_link); 707 } else { 708 ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, 709 DNS_EVENT_DISPATCH, 710 resp->action, resp->arg, resp, NULL, NULL); 711 request_log(disp, resp, LVL(90), 712 "[a] Sent event %p buffer %p len %d to task %p", 713 rev, rev->buffer.base, rev->buffer.length, 714 resp->task); 715 resp->item_out = ISC_TRUE; 716 isc_task_send(resp->task, ISC_EVENT_PTR(&rev)); 717 } 718 unlock: 719 UNLOCK(&qid->lock); 720 721 /* 722 * Restart recv() to get the next packet. 723 */ 724 restart: 725 startrecv(disp); 726 727 UNLOCK(&disp->lock); 728 729 isc_event_free(&ev_in); 730} 731 732/* 733 * General flow: 734 * 735 * If I/O result == CANCELED, EOF, or error, notify everyone as the 736 * various queues drain. 737 * 738 * If query, restart. 739 * 740 * If response: 741 * Allocate event, fill in details. 742 * If cannot allocate, restart. 743 * find target. If not found, restart. 744 * if event queue is not empty, queue. else, send. 745 * restart. 746 */ 747static void 748tcp_recv(isc_task_t *task, isc_event_t *ev_in) { 749 dns_dispatch_t *disp = ev_in->ev_arg; 750 dns_tcpmsg_t *tcpmsg = &disp->tcpmsg; 751 dns_messageid_t id; 752 isc_result_t dres; 753 unsigned int flags; 754 dns_dispentry_t *resp; 755 dns_dispatchevent_t *rev; 756 unsigned int bucket; 757 isc_boolean_t killit; 758 isc_boolean_t queue_response; 759 dns_qid_t *qid; 760 int level; 761 char buf[ISC_SOCKADDR_FORMATSIZE]; 762 763 UNUSED(task); 764 765 REQUIRE(VALID_DISPATCH(disp)); 766 767 qid = disp->qid; 768 769 dispatch_log(disp, LVL(90), 770 "got TCP packet: requests %d, buffers %d, recvs %d", 771 disp->requests, disp->tcpbuffers, disp->recv_pending); 772 773 LOCK(&disp->lock); 774 775 INSIST(disp->recv_pending != 0); 776 disp->recv_pending = 0; 777 778 if (disp->refcount == 0) { 779 /* 780 * This dispatcher is shutting down. Force cancelation. 781 */ 782 tcpmsg->result = ISC_R_CANCELED; 783 } 784 785 if (tcpmsg->result != ISC_R_SUCCESS) { 786 switch (tcpmsg->result) { 787 case ISC_R_CANCELED: 788 break; 789 790 case ISC_R_EOF: 791 dispatch_log(disp, LVL(90), "shutting down on EOF"); 792 do_cancel(disp); 793 break; 794 795 case ISC_R_CONNECTIONRESET: 796 level = ISC_LOG_INFO; 797 goto logit; 798 799 default: 800 level = ISC_LOG_ERROR; 801 logit: 802 isc_sockaddr_format(&tcpmsg->address, buf, sizeof(buf)); 803 dispatch_log(disp, level, "shutting down due to TCP " 804 "receive error: %s: %s", buf, 805 isc_result_totext(tcpmsg->result)); 806 do_cancel(disp); 807 break; 808 } 809 810 /* 811 * The event is statically allocated in the tcpmsg 812 * structure, and destroy_disp() frees the tcpmsg, so we must 813 * free the event *before* calling destroy_disp(). 814 */ 815 isc_event_free(&ev_in); 816 817 disp->shutting_down = 1; 818 disp->shutdown_why = tcpmsg->result; 819 820 /* 821 * If the recv() was canceled pass the word on. 822 */ 823 killit = destroy_disp_ok(disp); 824 UNLOCK(&disp->lock); 825 if (killit) 826 isc_task_send(disp->task, &disp->ctlevent); 827 return; 828 } 829 830 dispatch_log(disp, LVL(90), "result %d, length == %d, addr = %p", 831 tcpmsg->result, 832 tcpmsg->buffer.length, tcpmsg->buffer.base); 833 834 /* 835 * Peek into the buffer to see what we can see. 836 */ 837 dres = dns_message_peekheader(&tcpmsg->buffer, &id, &flags); 838 if (dres != ISC_R_SUCCESS) { 839 dispatch_log(disp, LVL(10), "got garbage packet"); 840 goto restart; 841 } 842 843 dispatch_log(disp, LVL(92), 844 "got valid DNS message header, /QR %c, id %u", 845 ((flags & DNS_MESSAGEFLAG_QR) ? '1' : '0'), id); 846 847 /* 848 * Allocate an event to send to the query or response client, and 849 * allocate a new buffer for our use. 850 */ 851 852 /* 853 * Look at flags. If query, drop it. If response, 854 * look to see where it goes. 855 */ 856 queue_response = ISC_FALSE; 857 if ((flags & DNS_MESSAGEFLAG_QR) == 0) { 858 /* 859 * Query. 860 */ 861 goto restart; 862 } 863 864 dns_dispatch_hash(tcpmsg->buffer.base, tcpmsg->buffer.length); 865 866 /* 867 * Response. 868 */ 869 bucket = dns_hash(qid, &tcpmsg->address, id); 870 LOCK(&qid->lock); 871 resp = bucket_search(qid, &tcpmsg->address, id, bucket); 872 dispatch_log(disp, LVL(90), 873 "search for response in bucket %d: %s", 874 bucket, (resp == NULL ? "not found" : "found")); 875 876 if (resp == NULL) 877 goto unlock; 878 queue_response = resp->item_out; 879 rev = allocate_event(disp); 880 if (rev == NULL) 881 goto unlock; 882 883 /* 884 * At this point, rev contains the event we want to fill in, and 885 * resp contains the information on the place to send it to. 886 * Send the event off. 887 */ 888 dns_tcpmsg_keepbuffer(tcpmsg, &rev->buffer); 889 disp->tcpbuffers++; 890 rev->result = ISC_R_SUCCESS; 891 rev->id = id; 892 rev->addr = tcpmsg->address; 893 if (queue_response) { 894 ISC_LIST_APPEND(resp->items, rev, ev_link); 895 } else { 896 ISC_EVENT_INIT(rev, sizeof(*rev), 0, NULL, DNS_EVENT_DISPATCH, 897 resp->action, resp->arg, resp, NULL, NULL); 898 request_log(disp, resp, LVL(90), 899 "[b] Sent event %p buffer %p len %d to task %p", 900 rev, rev->buffer.base, rev->buffer.length, 901 resp->task); 902 resp->item_out = ISC_TRUE; 903 isc_task_send(resp->task, ISC_EVENT_PTR(&rev)); 904 } 905 unlock: 906 UNLOCK(&qid->lock); 907 908 /* 909 * Restart recv() to get the next packet. 910 */ 911 restart: 912 startrecv(disp); 913 914 UNLOCK(&disp->lock); 915 916 isc_event_free(&ev_in); 917} 918 919/* 920 * disp must be locked. 921 */ 922static void 923startrecv(dns_dispatch_t *disp) { 924 isc_result_t res; 925 isc_region_t region; 926 927 if (disp->shutting_down == 1) 928 return; 929 930 if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) 931 return; 932 933 if (disp->recv_pending != 0) 934 return; 935 936 if (disp->mgr->buffers >= disp->mgr->maxbuffers) 937 return; 938 939 switch (disp->socktype) { 940 /* 941 * UDP reads are always maximal. 942 */ 943 case isc_sockettype_udp: 944 region.length = disp->mgr->buffersize; 945 region.base = allocate_udp_buffer(disp); 946 if (region.base == NULL) 947 return; 948 res = isc_socket_recv(disp->socket, ®ion, 1, 949 disp->task, udp_recv, disp); 950 if (res != ISC_R_SUCCESS) { 951 free_buffer(disp, region.base, region.length); 952 disp->shutdown_why = res; 953 disp->shutting_down = 1; 954 do_cancel(disp); 955 return; 956 } 957 INSIST(disp->recv_pending == 0); 958 disp->recv_pending = 1; 959 break; 960 961 case isc_sockettype_tcp: 962 res = dns_tcpmsg_readmessage(&disp->tcpmsg, disp->task, 963 tcp_recv, disp); 964 if (res != ISC_R_SUCCESS) { 965 disp->shutdown_why = res; 966 disp->shutting_down = 1; 967 do_cancel(disp); 968 return; 969 } 970 INSIST(disp->recv_pending == 0); 971 disp->recv_pending = 1; 972 break; 973 default: 974 INSIST(0); 975 break; 976 } 977} 978 979/* 980 * Mgr must be locked when calling this function. 981 */ 982static isc_boolean_t 983destroy_mgr_ok(dns_dispatchmgr_t *mgr) { 984 mgr_log(mgr, LVL(90), 985 "destroy_mgr_ok: shuttingdown=%d, listnonempty=%d, " 986 "epool=%d, rpool=%d, dpool=%d", 987 MGR_IS_SHUTTINGDOWN(mgr), !ISC_LIST_EMPTY(mgr->list), 988 isc_mempool_getallocated(mgr->epool), 989 isc_mempool_getallocated(mgr->rpool), 990 isc_mempool_getallocated(mgr->dpool)); 991 if (!MGR_IS_SHUTTINGDOWN(mgr)) 992 return (ISC_FALSE); 993 if (!ISC_LIST_EMPTY(mgr->list)) 994 return (ISC_FALSE); 995 if (isc_mempool_getallocated(mgr->epool) != 0) 996 return (ISC_FALSE); 997 if (isc_mempool_getallocated(mgr->rpool) != 0) 998 return (ISC_FALSE); 999 if (isc_mempool_getallocated(mgr->dpool) != 0) 1000 return (ISC_FALSE); 1001 1002 return (ISC_TRUE); 1003} 1004 1005/* 1006 * Mgr must be unlocked when calling this function. 1007 */ 1008static void 1009destroy_mgr(dns_dispatchmgr_t **mgrp) { 1010 isc_mem_t *mctx; 1011 dns_dispatchmgr_t *mgr; 1012 1013 mgr = *mgrp; 1014 *mgrp = NULL; 1015 1016 mctx = mgr->mctx; 1017 1018 mgr->magic = 0; 1019 mgr->mctx = NULL; 1020 DESTROYLOCK(&mgr->lock); 1021 mgr->state = 0; 1022 1023 isc_mempool_destroy(&mgr->epool); 1024 isc_mempool_destroy(&mgr->rpool); 1025 isc_mempool_destroy(&mgr->dpool); 1026 isc_mempool_destroy(&mgr->bpool); 1027 1028 DESTROYLOCK(&mgr->pool_lock); 1029 1030 if (mgr->entropy != NULL) 1031 isc_entropy_detach(&mgr->entropy); 1032 if (mgr->qid != NULL) 1033 qid_destroy(mctx, &mgr->qid); 1034 1035 DESTROYLOCK(&mgr->buffer_lock); 1036 1037 if (mgr->blackhole != NULL) 1038 dns_acl_detach(&mgr->blackhole); 1039 1040 if (mgr->portlist != NULL) 1041 dns_portlist_detach(&mgr->portlist); 1042 1043 isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t)); 1044 isc_mem_detach(&mctx); 1045} 1046 1047static isc_result_t 1048create_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local, 1049 isc_socket_t **sockp) 1050{ 1051 isc_socket_t *sock; 1052 isc_result_t result; 1053 1054 sock = NULL; 1055 result = isc_socket_create(mgr, isc_sockaddr_pf(local), 1056 isc_sockettype_udp, &sock); 1057 if (result != ISC_R_SUCCESS) 1058 return (result); 1059 1060#ifndef ISC_ALLOW_MAPPED 1061 isc_socket_ipv6only(sock, ISC_TRUE); 1062#endif 1063 result = isc_socket_bind(sock, local); 1064 if (result != ISC_R_SUCCESS) { 1065 isc_socket_detach(&sock); 1066 return (result); 1067 } 1068 1069 *sockp = sock; 1070 return (ISC_R_SUCCESS); 1071} 1072 1073/* 1074 * Publics. 1075 */ 1076 1077isc_result_t 1078dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, 1079 dns_dispatchmgr_t **mgrp) 1080{ 1081 dns_dispatchmgr_t *mgr; 1082 isc_result_t result; 1083 1084 REQUIRE(mctx != NULL); 1085 REQUIRE(mgrp != NULL && *mgrp == NULL); 1086 1087 mgr = isc_mem_get(mctx, sizeof(dns_dispatchmgr_t)); 1088 if (mgr == NULL) 1089 return (ISC_R_NOMEMORY); 1090 1091 mgr->mctx = NULL; 1092 isc_mem_attach(mctx, &mgr->mctx); 1093 1094 mgr->blackhole = NULL; 1095 mgr->portlist = NULL; 1096 1097 result = isc_mutex_init(&mgr->lock); 1098 if (result != ISC_R_SUCCESS) 1099 goto deallocate; 1100 1101 result = isc_mutex_init(&mgr->buffer_lock); 1102 if (result != ISC_R_SUCCESS) 1103 goto kill_lock; 1104 1105 result = isc_mutex_init(&mgr->pool_lock); 1106 if (result != ISC_R_SUCCESS) 1107 goto kill_buffer_lock; 1108 1109 mgr->epool = NULL; 1110 if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatchevent_t), 1111 &mgr->epool) != ISC_R_SUCCESS) { 1112 result = ISC_R_NOMEMORY; 1113 goto kill_pool_lock; 1114 } 1115 1116 mgr->rpool = NULL; 1117 if (isc_mempool_create(mgr->mctx, sizeof(dns_dispentry_t), 1118 &mgr->rpool) != ISC_R_SUCCESS) { 1119 result = ISC_R_NOMEMORY; 1120 goto kill_epool; 1121 } 1122 1123 mgr->dpool = NULL; 1124 if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatch_t), 1125 &mgr->dpool) != ISC_R_SUCCESS) { 1126 result = ISC_R_NOMEMORY; 1127 goto kill_rpool; 1128 } 1129 1130 isc_mempool_setname(mgr->epool, "dispmgr_epool"); 1131 isc_mempool_setfreemax(mgr->epool, 1024); 1132 isc_mempool_associatelock(mgr->epool, &mgr->pool_lock); 1133 1134 isc_mempool_setname(mgr->rpool, "dispmgr_rpool"); 1135 isc_mempool_setfreemax(mgr->rpool, 1024); 1136 isc_mempool_associatelock(mgr->rpool, &mgr->pool_lock); 1137 1138 isc_mempool_setname(mgr->dpool, "dispmgr_dpool"); 1139 isc_mempool_setfreemax(mgr->dpool, 1024); 1140 isc_mempool_associatelock(mgr->dpool, &mgr->pool_lock); 1141 1142 mgr->buffers = 0; 1143 mgr->buffersize = 0; 1144 mgr->maxbuffers = 0; 1145 mgr->bpool = NULL; 1146 mgr->entropy = NULL; 1147 mgr->qid = NULL; 1148 mgr->state = 0; 1149 ISC_LIST_INIT(mgr->list); 1150 mgr->magic = DNS_DISPATCHMGR_MAGIC; 1151 1152 if (entropy != NULL) 1153 isc_entropy_attach(entropy, &mgr->entropy); 1154 1155 *mgrp = mgr; 1156 return (ISC_R_SUCCESS); 1157 1158 kill_rpool: 1159 isc_mempool_destroy(&mgr->rpool); 1160 kill_epool: 1161 isc_mempool_destroy(&mgr->epool); 1162 kill_pool_lock: 1163 DESTROYLOCK(&mgr->pool_lock); 1164 kill_buffer_lock: 1165 DESTROYLOCK(&mgr->buffer_lock); 1166 kill_lock: 1167 DESTROYLOCK(&mgr->lock); 1168 deallocate: 1169 isc_mem_put(mctx, mgr, sizeof(dns_dispatchmgr_t)); 1170 isc_mem_detach(&mctx); 1171 1172 return (result); 1173} 1174 1175void 1176dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole) { 1177 REQUIRE(VALID_DISPATCHMGR(mgr)); 1178 if (mgr->blackhole != NULL) 1179 dns_acl_detach(&mgr->blackhole); 1180 dns_acl_attach(blackhole, &mgr->blackhole); 1181} 1182 1183dns_acl_t * 1184dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr) { 1185 REQUIRE(VALID_DISPATCHMGR(mgr)); 1186 return (mgr->blackhole); 1187} 1188 1189void 1190dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr, 1191 dns_portlist_t *portlist) 1192{ 1193 REQUIRE(VALID_DISPATCHMGR(mgr)); 1194 if (mgr->portlist != NULL) 1195 dns_portlist_detach(&mgr->portlist); 1196 if (portlist != NULL) 1197 dns_portlist_attach(portlist, &mgr->portlist); 1198} 1199 1200dns_portlist_t * 1201dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr) { 1202 REQUIRE(VALID_DISPATCHMGR(mgr)); 1203 return (mgr->portlist); 1204} 1205 1206static isc_result_t 1207dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr, 1208 unsigned int buffersize, unsigned int maxbuffers, 1209 unsigned int buckets, unsigned int increment) 1210{ 1211 isc_result_t result; 1212 1213 REQUIRE(VALID_DISPATCHMGR(mgr)); 1214 REQUIRE(buffersize >= 512 && buffersize < (64 * 1024)); 1215 REQUIRE(maxbuffers > 0); 1216 REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ 1217 REQUIRE(increment > buckets); 1218 1219 /* 1220 * Keep some number of items around. This should be a config 1221 * option. For now, keep 8, but later keep at least two even 1222 * if the caller wants less. This allows us to ensure certain 1223 * things, like an event can be "freed" and the next allocation 1224 * will always succeed. 1225 * 1226 * Note that if limits are placed on anything here, we use one 1227 * event internally, so the actual limit should be "wanted + 1." 1228 * 1229 * XXXMLG 1230 */ 1231 1232 if (maxbuffers < 8) 1233 maxbuffers = 8; 1234 1235 LOCK(&mgr->buffer_lock); 1236 if (mgr->bpool != NULL) { 1237 isc_mempool_setmaxalloc(mgr->bpool, maxbuffers); 1238 mgr->maxbuffers = maxbuffers; 1239 UNLOCK(&mgr->buffer_lock); 1240 return (ISC_R_SUCCESS); 1241 } 1242 1243 if (isc_mempool_create(mgr->mctx, buffersize, 1244 &mgr->bpool) != ISC_R_SUCCESS) { 1245 UNLOCK(&mgr->buffer_lock); 1246 return (ISC_R_NOMEMORY); 1247 } 1248 1249 isc_mempool_setname(mgr->bpool, "dispmgr_bpool"); 1250 isc_mempool_setmaxalloc(mgr->bpool, maxbuffers); 1251 isc_mempool_associatelock(mgr->bpool, &mgr->pool_lock); 1252 1253 result = qid_allocate(mgr, buckets, increment, ISC_TRUE, &mgr->qid); 1254 if (result != ISC_R_SUCCESS) 1255 goto cleanup; 1256 1257 mgr->buffersize = buffersize; 1258 mgr->maxbuffers = maxbuffers; 1259 UNLOCK(&mgr->buffer_lock); 1260 return (ISC_R_SUCCESS); 1261 1262 cleanup: 1263 isc_mempool_destroy(&mgr->bpool); 1264 UNLOCK(&mgr->buffer_lock); 1265 return (ISC_R_NOMEMORY); 1266} 1267 1268void 1269dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp) { 1270 dns_dispatchmgr_t *mgr; 1271 isc_boolean_t killit; 1272 1273 REQUIRE(mgrp != NULL); 1274 REQUIRE(VALID_DISPATCHMGR(*mgrp)); 1275 1276 mgr = *mgrp; 1277 *mgrp = NULL; 1278 1279 LOCK(&mgr->lock); 1280 mgr->state |= MGR_SHUTTINGDOWN; 1281 1282 killit = destroy_mgr_ok(mgr); 1283 UNLOCK(&mgr->lock); 1284 1285 mgr_log(mgr, LVL(90), "destroy: killit=%d", killit); 1286 1287 if (killit) 1288 destroy_mgr(&mgr); 1289} 1290 1291static isc_boolean_t 1292blacklisted(dns_dispatchmgr_t *mgr, isc_socket_t *sock) { 1293 isc_sockaddr_t sockaddr; 1294 isc_result_t result; 1295 1296 if (mgr->portlist == NULL) 1297 return (ISC_FALSE); 1298 1299 result = isc_socket_getsockname(sock, &sockaddr); 1300 if (result != ISC_R_SUCCESS) 1301 return (ISC_FALSE); 1302 1303 if (mgr->portlist != NULL && 1304 dns_portlist_match(mgr->portlist, isc_sockaddr_pf(&sockaddr), 1305 isc_sockaddr_getport(&sockaddr))) 1306 return (ISC_TRUE); 1307 return (ISC_FALSE); 1308} 1309 1310#define ATTRMATCH(_a1, _a2, _mask) (((_a1) & (_mask)) == ((_a2) & (_mask))) 1311 1312static isc_boolean_t 1313local_addr_match(dns_dispatch_t *disp, isc_sockaddr_t *addr) { 1314 isc_sockaddr_t sockaddr; 1315 isc_result_t result; 1316 1317 if (addr == NULL) 1318 return (ISC_TRUE); 1319 1320 /* 1321 * Don't match wildcard ports against newly blacklisted ports. 1322 */ 1323 if (disp->mgr->portlist != NULL && 1324 isc_sockaddr_getport(addr) == 0 && 1325 isc_sockaddr_getport(&disp->local) == 0 && 1326 blacklisted(disp->mgr, disp->socket)) 1327 return (ISC_FALSE); 1328 1329 /* 1330 * Check if we match the binding <address,port>. 1331 * Wildcard ports match/fail here. 1332 */ 1333 if (isc_sockaddr_equal(&disp->local, addr)) 1334 return (ISC_TRUE); 1335 if (isc_sockaddr_getport(addr) == 0) 1336 return (ISC_FALSE); 1337 1338 /* 1339 * Check if we match a bound wildcard port <address,port>. 1340 */ 1341 if (!isc_sockaddr_eqaddr(&disp->local, addr)) 1342 return (ISC_FALSE); 1343 result = isc_socket_getsockname(disp->socket, &sockaddr); 1344 if (result != ISC_R_SUCCESS) 1345 return (ISC_FALSE); 1346 1347 return (isc_sockaddr_equal(&sockaddr, addr)); 1348} 1349 1350/* 1351 * Requires mgr be locked. 1352 * 1353 * No dispatcher can be locked by this thread when calling this function. 1354 * 1355 * 1356 * NOTE: 1357 * If a matching dispatcher is found, it is locked after this function 1358 * returns, and must be unlocked by the caller. 1359 */ 1360static isc_result_t 1361dispatch_find(dns_dispatchmgr_t *mgr, isc_sockaddr_t *local, 1362 unsigned int attributes, unsigned int mask, 1363 dns_dispatch_t **dispp) 1364{ 1365 dns_dispatch_t *disp; 1366 isc_result_t result; 1367 1368 /* 1369 * Make certain that we will not match a private dispatch. 1370 */ 1371 attributes &= ~DNS_DISPATCHATTR_PRIVATE; 1372 mask |= DNS_DISPATCHATTR_PRIVATE; 1373 1374 disp = ISC_LIST_HEAD(mgr->list); 1375 while (disp != NULL) { 1376 LOCK(&disp->lock); 1377 if ((disp->shutting_down == 0) 1378 && ATTRMATCH(disp->attributes, attributes, mask) 1379 && local_addr_match(disp, local)) 1380 break; 1381 UNLOCK(&disp->lock); 1382 disp = ISC_LIST_NEXT(disp, link); 1383 } 1384 1385 if (disp == NULL) { 1386 result = ISC_R_NOTFOUND; 1387 goto out; 1388 } 1389 1390 *dispp = disp; 1391 result = ISC_R_SUCCESS; 1392 out: 1393 1394 return (result); 1395} 1396 1397static isc_result_t 1398qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets, 1399 unsigned int increment, isc_boolean_t usepool, dns_qid_t **qidp) 1400{ 1401 dns_qid_t *qid; 1402 unsigned int i; 1403 isc_result_t result; 1404 1405 REQUIRE(VALID_DISPATCHMGR(mgr)); 1406 REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ 1407 REQUIRE(increment > buckets); 1408 REQUIRE(qidp != NULL && *qidp == NULL); 1409 1410 qid = isc_mem_get(mgr->mctx, sizeof(*qid)); 1411 if (qid == NULL) 1412 return (ISC_R_NOMEMORY); 1413 1414 qid->qid_table = isc_mem_get(mgr->mctx, 1415 buckets * sizeof(dns_displist_t)); 1416 if (qid->qid_table == NULL) { 1417 isc_mem_put(mgr->mctx, qid, sizeof(*qid)); 1418 return (ISC_R_NOMEMORY); 1419 } 1420 1421 result = nsid_init(mgr->mctx, &qid->nsid, usepool); 1422 if (result != ISC_R_SUCCESS) { 1423 isc_mem_put(mgr->mctx, qid->qid_table, 1424 buckets * sizeof(dns_displist_t)); 1425 isc_mem_put(mgr->mctx, qid, sizeof(*qid)); 1426 return (ISC_R_NOMEMORY); 1427 } 1428 1429 result = isc_mutex_init(&qid->lock); 1430 if (result != ISC_R_SUCCESS) { 1431 nsid_destroy(mgr->mctx, &qid->nsid); 1432 isc_mem_put(mgr->mctx, qid->qid_table, 1433 buckets * sizeof(dns_displist_t)); 1434 isc_mem_put(mgr->mctx, qid, sizeof(*qid)); 1435 return (result); 1436 } 1437 1438 for (i = 0; i < buckets; i++) 1439 ISC_LIST_INIT(qid->qid_table[i]); 1440 1441 qid->qid_nbuckets = buckets; 1442 qid->qid_increment = increment; 1443 qid->magic = QID_MAGIC; 1444 *qidp = qid; 1445 return (ISC_R_SUCCESS); 1446} 1447 1448static void 1449qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp) { 1450 dns_qid_t *qid; 1451 1452 REQUIRE(qidp != NULL); 1453 qid = *qidp; 1454 1455 REQUIRE(VALID_QID(qid)); 1456 1457 *qidp = NULL; 1458 qid->magic = 0; 1459 nsid_destroy(mctx, &qid->nsid); 1460 isc_mem_put(mctx, qid->qid_table, 1461 qid->qid_nbuckets * sizeof(dns_displist_t)); 1462 DESTROYLOCK(&qid->lock); 1463 isc_mem_put(mctx, qid, sizeof(*qid)); 1464} 1465 1466/* 1467 * Allocate and set important limits. 1468 */ 1469static isc_result_t 1470dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests, 1471 dns_dispatch_t **dispp) 1472{ 1473 dns_dispatch_t *disp; 1474 isc_result_t result; 1475 1476 REQUIRE(VALID_DISPATCHMGR(mgr)); 1477 REQUIRE(dispp != NULL && *dispp == NULL); 1478 1479 /* 1480 * Set up the dispatcher, mostly. Don't bother setting some of 1481 * the options that are controlled by tcp vs. udp, etc. 1482 */ 1483 1484 disp = isc_mempool_get(mgr->dpool); 1485 if (disp == NULL) 1486 return (ISC_R_NOMEMORY); 1487 1488 disp->magic = 0; 1489 disp->mgr = mgr; 1490 disp->maxrequests = maxrequests; 1491 disp->attributes = 0; 1492 ISC_LINK_INIT(disp, link); 1493 disp->refcount = 1; 1494 disp->recv_pending = 0; 1495 memset(&disp->local, 0, sizeof(disp->local)); 1496 disp->shutting_down = 0; 1497 disp->shutdown_out = 0; 1498 disp->connected = 0; 1499 disp->tcpmsg_valid = 0; 1500 disp->shutdown_why = ISC_R_UNEXPECTED; 1501 disp->requests = 0; 1502 disp->tcpbuffers = 0; 1503 disp->qid = NULL; 1504 1505 result = isc_mutex_init(&disp->lock); 1506 if (result != ISC_R_SUCCESS) 1507 goto deallocate; 1508 1509 disp->failsafe_ev = allocate_event(disp); 1510 if (disp->failsafe_ev == NULL) { 1511 result = ISC_R_NOMEMORY; 1512 goto kill_lock; 1513 } 1514 1515 disp->magic = DISPATCH_MAGIC; 1516 1517 *dispp = disp; 1518 return (ISC_R_SUCCESS); 1519 1520 /* 1521 * error returns 1522 */ 1523 kill_lock: 1524 DESTROYLOCK(&disp->lock); 1525 deallocate: 1526 isc_mempool_put(mgr->dpool, disp); 1527 1528 return (result); 1529} 1530 1531 1532/* 1533 * MUST be unlocked, and not used by anthing. 1534 */ 1535static void 1536dispatch_free(dns_dispatch_t **dispp) 1537{ 1538 dns_dispatch_t *disp; 1539 dns_dispatchmgr_t *mgr; 1540 1541 REQUIRE(VALID_DISPATCH(*dispp)); 1542 disp = *dispp; 1543 *dispp = NULL; 1544 1545 mgr = disp->mgr; 1546 REQUIRE(VALID_DISPATCHMGR(mgr)); 1547 1548 if (disp->tcpmsg_valid) { 1549 dns_tcpmsg_invalidate(&disp->tcpmsg); 1550 disp->tcpmsg_valid = 0; 1551 } 1552 1553 INSIST(disp->tcpbuffers == 0); 1554 INSIST(disp->requests == 0); 1555 INSIST(disp->recv_pending == 0); 1556 1557 isc_mempool_put(mgr->epool, disp->failsafe_ev); 1558 disp->failsafe_ev = NULL; 1559 1560 if (disp->qid != NULL) 1561 qid_destroy(mgr->mctx, &disp->qid); 1562 disp->mgr = NULL; 1563 DESTROYLOCK(&disp->lock); 1564 disp->magic = 0; 1565 isc_mempool_put(mgr->dpool, disp); 1566} 1567 1568isc_result_t 1569dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, 1570 isc_taskmgr_t *taskmgr, unsigned int buffersize, 1571 unsigned int maxbuffers, unsigned int maxrequests, 1572 unsigned int buckets, unsigned int increment, 1573 unsigned int attributes, dns_dispatch_t **dispp) 1574{ 1575 isc_result_t result; 1576 dns_dispatch_t *disp; 1577 1578 UNUSED(maxbuffers); 1579 UNUSED(buffersize); 1580 1581 REQUIRE(VALID_DISPATCHMGR(mgr)); 1582 REQUIRE(isc_socket_gettype(sock) == isc_sockettype_tcp); 1583 REQUIRE((attributes & DNS_DISPATCHATTR_TCP) != 0); 1584 REQUIRE((attributes & DNS_DISPATCHATTR_UDP) == 0); 1585 1586 attributes |= DNS_DISPATCHATTR_PRIVATE; /* XXXMLG */ 1587 1588 LOCK(&mgr->lock); 1589 1590 /* 1591 * dispatch_allocate() checks mgr for us. 1592 * qid_allocate() checks buckets and increment for us. 1593 */ 1594 disp = NULL; 1595 result = dispatch_allocate(mgr, maxrequests, &disp); 1596 if (result != ISC_R_SUCCESS) { 1597 UNLOCK(&mgr->lock); 1598 return (result); 1599 } 1600 1601 result = qid_allocate(mgr, buckets, increment, ISC_FALSE, &disp->qid); 1602 if (result != ISC_R_SUCCESS) 1603 goto deallocate_dispatch; 1604 1605 disp->socktype = isc_sockettype_tcp; 1606 disp->socket = NULL; 1607 isc_socket_attach(sock, &disp->socket); 1608 1609 disp->task = NULL; 1610 result = isc_task_create(taskmgr, 0, &disp->task); 1611 if (result != ISC_R_SUCCESS) 1612 goto kill_socket; 1613 1614 disp->ctlevent = isc_event_allocate(mgr->mctx, disp, 1615 DNS_EVENT_DISPATCHCONTROL, 1616 destroy_disp, disp, 1617 sizeof(isc_event_t)); 1618 if (disp->ctlevent == NULL) 1619 goto kill_task; 1620 1621 isc_task_setname(disp->task, "tcpdispatch", disp); 1622 1623 dns_tcpmsg_init(mgr->mctx, disp->socket, &disp->tcpmsg); 1624 disp->tcpmsg_valid = 1; 1625 1626 disp->attributes = attributes; 1627 1628 /* 1629 * Append it to the dispatcher list. 1630 */ 1631 ISC_LIST_APPEND(mgr->list, disp, link); 1632 UNLOCK(&mgr->lock); 1633 1634 mgr_log(mgr, LVL(90), "created TCP dispatcher %p", disp); 1635 dispatch_log(disp, LVL(90), "created task %p", disp->task); 1636 1637 *dispp = disp; 1638 1639 return (ISC_R_SUCCESS); 1640 1641 /* 1642 * Error returns. 1643 */ 1644 kill_task: 1645 isc_task_detach(&disp->task); 1646 kill_socket: 1647 isc_socket_detach(&disp->socket); 1648 deallocate_dispatch: 1649 dispatch_free(&disp); 1650 1651 UNLOCK(&mgr->lock); 1652 1653 return (result); 1654} 1655 1656isc_result_t 1657dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, 1658 isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, 1659 unsigned int buffersize, 1660 unsigned int maxbuffers, unsigned int maxrequests, 1661 unsigned int buckets, unsigned int increment, 1662 unsigned int attributes, unsigned int mask, 1663 dns_dispatch_t **dispp) 1664{ 1665 isc_result_t result; 1666 dns_dispatch_t *disp; 1667 1668 REQUIRE(VALID_DISPATCHMGR(mgr)); 1669 REQUIRE(sockmgr != NULL); 1670 REQUIRE(localaddr != NULL); 1671 REQUIRE(taskmgr != NULL); 1672 REQUIRE(buffersize >= 512 && buffersize < (64 * 1024)); 1673 REQUIRE(maxbuffers > 0); 1674 REQUIRE(buckets < 2097169); /* next prime > 65536 * 32 */ 1675 REQUIRE(increment > buckets); 1676 REQUIRE(dispp != NULL && *dispp == NULL); 1677 REQUIRE((attributes & DNS_DISPATCHATTR_TCP) == 0); 1678 1679 result = dns_dispatchmgr_setudp(mgr, buffersize, maxbuffers, 1680 buckets, increment); 1681 if (result != ISC_R_SUCCESS) 1682 return (result); 1683 1684 LOCK(&mgr->lock); 1685 1686 /* 1687 * First, see if we have a dispatcher that matches. 1688 */ 1689 disp = NULL; 1690 result = dispatch_find(mgr, localaddr, attributes, mask, &disp); 1691 if (result == ISC_R_SUCCESS) { 1692 disp->refcount++; 1693 1694 if (disp->maxrequests < maxrequests) 1695 disp->maxrequests = maxrequests; 1696 1697 if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) == 0 && 1698 (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) 1699 { 1700 disp->attributes |= DNS_DISPATCHATTR_NOLISTEN; 1701 if (disp->recv_pending != 0) 1702 isc_socket_cancel(disp->socket, disp->task, 1703 ISC_SOCKCANCEL_RECV); 1704 } 1705 1706 UNLOCK(&disp->lock); 1707 UNLOCK(&mgr->lock); 1708 1709 *dispp = disp; 1710 1711 return (ISC_R_SUCCESS); 1712 } 1713 1714 /* 1715 * Nope, create one. 1716 */ 1717 result = dispatch_createudp(mgr, sockmgr, taskmgr, localaddr, 1718 maxrequests, attributes, &disp); 1719 if (result != ISC_R_SUCCESS) { 1720 UNLOCK(&mgr->lock); 1721 return (result); 1722 } 1723 1724 UNLOCK(&mgr->lock); 1725 *dispp = disp; 1726 return (ISC_R_SUCCESS); 1727} 1728 1729/* 1730 * mgr should be locked. 1731 */ 1732 1733#ifndef DNS_DISPATCH_HELD 1734#define DNS_DISPATCH_HELD 20U 1735#endif 1736 1737static isc_result_t 1738dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, 1739 isc_taskmgr_t *taskmgr, 1740 isc_sockaddr_t *localaddr, 1741 unsigned int maxrequests, 1742 unsigned int attributes, 1743 dns_dispatch_t **dispp) 1744{ 1745 isc_result_t result; 1746 dns_dispatch_t *disp; 1747 isc_socket_t *sock = NULL; 1748 isc_socket_t *held[DNS_DISPATCH_HELD]; 1749 unsigned int i = 0, j = 0; 1750 1751 /* 1752 * dispatch_allocate() checks mgr for us. 1753 */ 1754 disp = NULL; 1755 result = dispatch_allocate(mgr, maxrequests, &disp); 1756 if (result != ISC_R_SUCCESS) 1757 return (result); 1758 1759 /* 1760 * Try to allocate a socket that is not on the blacklist. 1761 * Hold up to DNS_DISPATCH_HELD sockets to prevent the OS 1762 * from returning the same port to us too quickly. 1763 */ 1764 memset(held, 0, sizeof(held)); 1765 getsocket: 1766 result = create_socket(sockmgr, localaddr, &sock); 1767 if (result != ISC_R_SUCCESS) 1768 goto deallocate_dispatch; 1769 if (isc_sockaddr_getport(localaddr) == 0 && blacklisted(mgr, sock)) { 1770 if (held[i] != NULL) 1771 isc_socket_detach(&held[i]); 1772 held[i++] = sock; 1773 sock = NULL; 1774 if (i == DNS_DISPATCH_HELD) 1775 i = 0; 1776 if (j++ == 0xffffU) { 1777 mgr_log(mgr, ISC_LOG_ERROR, "avoid-v%s-udp-ports: " 1778 "unable to allocate a non-blacklisted port", 1779 isc_sockaddr_pf(localaddr) == AF_INET ? 1780 "4" : "6"); 1781 result = ISC_R_FAILURE; 1782 goto deallocate_dispatch; 1783 } 1784 goto getsocket; 1785 } 1786 1787 disp->socktype = isc_sockettype_udp; 1788 disp->socket = sock; 1789 disp->local = *localaddr; 1790 1791 disp->task = NULL; 1792 result = isc_task_create(taskmgr, 0, &disp->task); 1793 if (result != ISC_R_SUCCESS) 1794 goto kill_socket; 1795 1796 disp->ctlevent = isc_event_allocate(mgr->mctx, disp, 1797 DNS_EVENT_DISPATCHCONTROL, 1798 destroy_disp, disp, 1799 sizeof(isc_event_t)); 1800 if (disp->ctlevent == NULL) 1801 goto kill_task; 1802 1803 isc_task_setname(disp->task, "udpdispatch", disp); 1804 1805 attributes &= ~DNS_DISPATCHATTR_TCP; 1806 attributes |= DNS_DISPATCHATTR_UDP; 1807 disp->attributes = attributes; 1808 1809 /* 1810 * Append it to the dispatcher list. 1811 */ 1812 ISC_LIST_APPEND(mgr->list, disp, link); 1813 1814 mgr_log(mgr, LVL(90), "created UDP dispatcher %p", disp); 1815 dispatch_log(disp, LVL(90), "created task %p", disp->task); 1816 dispatch_log(disp, LVL(90), "created socket %p", disp->socket); 1817 1818 *dispp = disp; 1819 1820 goto cleanheld; 1821 1822 /* 1823 * Error returns. 1824 */ 1825 kill_task: 1826 isc_task_detach(&disp->task); 1827 kill_socket: 1828 isc_socket_detach(&disp->socket); 1829 deallocate_dispatch: 1830 dispatch_free(&disp); 1831 cleanheld: 1832 for (i = 0; i < DNS_DISPATCH_HELD; i++) 1833 if (held[i] != NULL) 1834 isc_socket_detach(&held[i]); 1835 return (result); 1836} 1837 1838void 1839dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp) { 1840 REQUIRE(VALID_DISPATCH(disp)); 1841 REQUIRE(dispp != NULL && *dispp == NULL); 1842 1843 LOCK(&disp->lock); 1844 disp->refcount++; 1845 UNLOCK(&disp->lock); 1846 1847 *dispp = disp; 1848} 1849 1850/* 1851 * It is important to lock the manager while we are deleting the dispatch, 1852 * since dns_dispatch_getudp will call dispatch_find, which returns to 1853 * the caller a dispatch but does not attach to it until later. _getudp 1854 * locks the manager, however, so locking it here will keep us from attaching 1855 * to a dispatcher that is in the process of going away. 1856 */ 1857void 1858dns_dispatch_detach(dns_dispatch_t **dispp) { 1859 dns_dispatch_t *disp; 1860 isc_boolean_t killit; 1861 1862 REQUIRE(dispp != NULL && VALID_DISPATCH(*dispp)); 1863 1864 disp = *dispp; 1865 *dispp = NULL; 1866 1867 LOCK(&disp->lock); 1868 1869 INSIST(disp->refcount > 0); 1870 disp->refcount--; 1871 killit = ISC_FALSE; 1872 if (disp->refcount == 0) { 1873 if (disp->recv_pending > 0) 1874 isc_socket_cancel(disp->socket, disp->task, 1875 ISC_SOCKCANCEL_RECV); 1876 disp->shutting_down = 1; 1877 } 1878 1879 dispatch_log(disp, LVL(90), "detach: refcount %d", disp->refcount); 1880 1881 killit = destroy_disp_ok(disp); 1882 UNLOCK(&disp->lock); 1883 if (killit) 1884 isc_task_send(disp->task, &disp->ctlevent); 1885} 1886 1887isc_result_t 1888dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest, 1889 isc_task_t *task, isc_taskaction_t action, void *arg, 1890 dns_messageid_t *idp, dns_dispentry_t **resp) 1891{ 1892 dns_dispentry_t *res; 1893 unsigned int bucket; 1894 dns_messageid_t id; 1895 int i; 1896 isc_boolean_t ok; 1897 dns_qid_t *qid; 1898 1899 REQUIRE(VALID_DISPATCH(disp)); 1900 REQUIRE(task != NULL); 1901 REQUIRE(dest != NULL); 1902 REQUIRE(resp != NULL && *resp == NULL); 1903 REQUIRE(idp != NULL); 1904 1905 LOCK(&disp->lock); 1906 1907 if (disp->shutting_down == 1) { 1908 UNLOCK(&disp->lock); 1909 return (ISC_R_SHUTTINGDOWN); 1910 } 1911 1912 if (disp->requests >= disp->maxrequests) { 1913 UNLOCK(&disp->lock); 1914 return (ISC_R_QUOTA); 1915 } 1916 1917 /* 1918 * Try somewhat hard to find an unique ID. 1919 */ 1920 qid = DNS_QID(disp); 1921 LOCK(&qid->lock); 1922 id = dns_randomid(&qid->nsid); 1923 bucket = dns_hash(qid, dest, id); 1924 ok = ISC_FALSE; 1925 for (i = 0; i < 64; i++) { 1926 if (bucket_search(qid, dest, id, bucket) == NULL) { 1927 ok = ISC_TRUE; 1928 break; 1929 } 1930 id += qid->qid_increment; 1931 id &= 0x0000ffff; 1932 bucket = dns_hash(qid, dest, id); 1933 } 1934 1935 if (!ok) { 1936 UNLOCK(&qid->lock); 1937 UNLOCK(&disp->lock); 1938 return (ISC_R_NOMORE); 1939 } 1940 1941 res = isc_mempool_get(disp->mgr->rpool); 1942 if (res == NULL) { 1943 UNLOCK(&qid->lock); 1944 UNLOCK(&disp->lock); 1945 return (ISC_R_NOMEMORY); 1946 } 1947 1948 disp->refcount++; 1949 disp->requests++; 1950 res->task = NULL; 1951 isc_task_attach(task, &res->task); 1952 res->disp = disp; 1953 res->id = id; 1954 res->bucket = bucket; 1955 res->host = *dest; 1956 res->action = action; 1957 res->arg = arg; 1958 res->item_out = ISC_FALSE; 1959 ISC_LIST_INIT(res->items); 1960 ISC_LINK_INIT(res, link); 1961 res->magic = RESPONSE_MAGIC; 1962 ISC_LIST_APPEND(qid->qid_table[bucket], res, link); 1963 UNLOCK(&qid->lock); 1964 1965 request_log(disp, res, LVL(90), 1966 "attached to task %p", res->task); 1967 1968 if (((disp->attributes & DNS_DISPATCHATTR_UDP) != 0) || 1969 ((disp->attributes & DNS_DISPATCHATTR_CONNECTED) != 0)) 1970 startrecv(disp); 1971 1972 UNLOCK(&disp->lock); 1973 1974 *idp = id; 1975 *resp = res; 1976 1977 return (ISC_R_SUCCESS); 1978} 1979 1980void 1981dns_dispatch_starttcp(dns_dispatch_t *disp) { 1982 1983 REQUIRE(VALID_DISPATCH(disp)); 1984 1985 dispatch_log(disp, LVL(90), "starttcp %p", disp->task); 1986 1987 LOCK(&disp->lock); 1988 disp->attributes |= DNS_DISPATCHATTR_CONNECTED; 1989 startrecv(disp); 1990 UNLOCK(&disp->lock); 1991} 1992 1993void 1994dns_dispatch_removeresponse(dns_dispentry_t **resp, 1995 dns_dispatchevent_t **sockevent) 1996{ 1997 dns_dispatchmgr_t *mgr; 1998 dns_dispatch_t *disp; 1999 dns_dispentry_t *res; 2000 dns_dispatchevent_t *ev; 2001 unsigned int bucket; 2002 isc_boolean_t killit; 2003 unsigned int n; 2004 isc_eventlist_t events; 2005 dns_qid_t *qid; 2006 2007 REQUIRE(resp != NULL); 2008 REQUIRE(VALID_RESPONSE(*resp)); 2009 2010 res = *resp; 2011 *resp = NULL; 2012 2013 disp = res->disp; 2014 REQUIRE(VALID_DISPATCH(disp)); 2015 mgr = disp->mgr; 2016 REQUIRE(VALID_DISPATCHMGR(mgr)); 2017 2018 qid = DNS_QID(disp); 2019 2020 if (sockevent != NULL) { 2021 REQUIRE(*sockevent != NULL); 2022 ev = *sockevent; 2023 *sockevent = NULL; 2024 } else { 2025 ev = NULL; 2026 } 2027 2028 LOCK(&disp->lock); 2029 2030 INSIST(disp->requests > 0); 2031 disp->requests--; 2032 INSIST(disp->refcount > 0); 2033 disp->refcount--; 2034 killit = ISC_FALSE; 2035 if (disp->refcount == 0) { 2036 if (disp->recv_pending > 0) 2037 isc_socket_cancel(disp->socket, disp->task, 2038 ISC_SOCKCANCEL_RECV); 2039 disp->shutting_down = 1; 2040 } 2041 2042 bucket = res->bucket; 2043 2044 LOCK(&qid->lock); 2045 ISC_LIST_UNLINK(qid->qid_table[bucket], res, link); 2046 UNLOCK(&qid->lock); 2047 2048 if (ev == NULL && res->item_out) { 2049 /* 2050 * We've posted our event, but the caller hasn't gotten it 2051 * yet. Take it back. 2052 */ 2053 ISC_LIST_INIT(events); 2054 n = isc_task_unsend(res->task, res, DNS_EVENT_DISPATCH, 2055 NULL, &events); 2056 /* 2057 * We had better have gotten it back. 2058 */ 2059 INSIST(n == 1); 2060 ev = (dns_dispatchevent_t *)ISC_LIST_HEAD(events); 2061 } 2062 2063 if (ev != NULL) { 2064 REQUIRE(res->item_out == ISC_TRUE); 2065 res->item_out = ISC_FALSE; 2066 if (ev->buffer.base != NULL) 2067 free_buffer(disp, ev->buffer.base, ev->buffer.length); 2068 free_event(disp, ev); 2069 } 2070 2071 request_log(disp, res, LVL(90), "detaching from task %p", res->task); 2072 isc_task_detach(&res->task); 2073 2074 /* 2075 * Free any buffered requests as well 2076 */ 2077 ev = ISC_LIST_HEAD(res->items); 2078 while (ev != NULL) { 2079 ISC_LIST_UNLINK(res->items, ev, ev_link); 2080 if (ev->buffer.base != NULL) 2081 free_buffer(disp, ev->buffer.base, ev->buffer.length); 2082 free_event(disp, ev); 2083 ev = ISC_LIST_HEAD(res->items); 2084 } 2085 res->magic = 0; 2086 isc_mempool_put(disp->mgr->rpool, res); 2087 if (disp->shutting_down == 1) 2088 do_cancel(disp); 2089 else 2090 startrecv(disp); 2091 2092 killit = destroy_disp_ok(disp); 2093 UNLOCK(&disp->lock); 2094 if (killit) 2095 isc_task_send(disp->task, &disp->ctlevent); 2096} 2097 2098static void 2099do_cancel(dns_dispatch_t *disp) { 2100 dns_dispatchevent_t *ev; 2101 dns_dispentry_t *resp; 2102 dns_qid_t *qid; 2103 2104 if (disp->shutdown_out == 1) 2105 return; 2106 2107 qid = DNS_QID(disp); 2108 2109 /* 2110 * Search for the first response handler without packets outstanding. 2111 */ 2112 LOCK(&qid->lock); 2113 for (resp = linear_first(qid); 2114 resp != NULL && resp->item_out != ISC_FALSE; 2115 /* Empty. */) 2116 resp = linear_next(qid, resp); 2117 /* 2118 * No one to send the cancel event to, so nothing to do. 2119 */ 2120 if (resp == NULL) 2121 goto unlock; 2122 2123 /* 2124 * Send the shutdown failsafe event to this resp. 2125 */ 2126 ev = disp->failsafe_ev; 2127 ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, DNS_EVENT_DISPATCH, 2128 resp->action, resp->arg, resp, NULL, NULL); 2129 ev->result = disp->shutdown_why; 2130 ev->buffer.base = NULL; 2131 ev->buffer.length = 0; 2132 disp->shutdown_out = 1; 2133 request_log(disp, resp, LVL(10), 2134 "cancel: failsafe event %p -> task %p", 2135 ev, resp->task); 2136 resp->item_out = ISC_TRUE; 2137 isc_task_send(resp->task, ISC_EVENT_PTR(&ev)); 2138 unlock: 2139 UNLOCK(&qid->lock); 2140} 2141 2142isc_socket_t * 2143dns_dispatch_getsocket(dns_dispatch_t *disp) { 2144 REQUIRE(VALID_DISPATCH(disp)); 2145 2146 return (disp->socket); 2147} 2148 2149isc_result_t 2150dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp) { 2151 2152 REQUIRE(VALID_DISPATCH(disp)); 2153 REQUIRE(addrp != NULL); 2154 2155 if (disp->socktype == isc_sockettype_udp) { 2156 *addrp = disp->local; 2157 return (ISC_R_SUCCESS); 2158 } 2159 return (ISC_R_NOTIMPLEMENTED); 2160} 2161 2162void 2163dns_dispatch_cancel(dns_dispatch_t *disp) { 2164 REQUIRE(VALID_DISPATCH(disp)); 2165 2166 LOCK(&disp->lock); 2167 2168 if (disp->shutting_down == 1) { 2169 UNLOCK(&disp->lock); 2170 return; 2171 } 2172 2173 disp->shutdown_why = ISC_R_CANCELED; 2174 disp->shutting_down = 1; 2175 do_cancel(disp); 2176 2177 UNLOCK(&disp->lock); 2178 2179 return; 2180} 2181 2182void 2183dns_dispatch_changeattributes(dns_dispatch_t *disp, 2184 unsigned int attributes, unsigned int mask) 2185{ 2186 REQUIRE(VALID_DISPATCH(disp)); 2187 2188 /* XXXMLG 2189 * Should check for valid attributes here! 2190 */ 2191 2192 LOCK(&disp->lock); 2193 2194 if ((mask & DNS_DISPATCHATTR_NOLISTEN) != 0) { 2195 if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0 && 2196 (attributes & DNS_DISPATCHATTR_NOLISTEN) == 0) { 2197 disp->attributes &= ~DNS_DISPATCHATTR_NOLISTEN; 2198 startrecv(disp); 2199 } else if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) 2200 == 0 && 2201 (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) { 2202 disp->attributes |= DNS_DISPATCHATTR_NOLISTEN; 2203 if (disp->recv_pending != 0) 2204 isc_socket_cancel(disp->socket, disp->task, 2205 ISC_SOCKCANCEL_RECV); 2206 } 2207 } 2208 2209 disp->attributes &= ~mask; 2210 disp->attributes |= (attributes & mask); 2211 UNLOCK(&disp->lock); 2212} 2213 2214void 2215dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event) { 2216 void *buf; 2217 isc_socketevent_t *sevent, *newsevent; 2218 2219 REQUIRE(VALID_DISPATCH(disp)); 2220 REQUIRE((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) != 0); 2221 REQUIRE(event != NULL); 2222 2223 sevent = (isc_socketevent_t *)event; 2224 2225 INSIST(sevent->n <= disp->mgr->buffersize); 2226 newsevent = (isc_socketevent_t *) 2227 isc_event_allocate(disp->mgr->mctx, NULL, 2228 DNS_EVENT_IMPORTRECVDONE, udp_recv, 2229 disp, sizeof(isc_socketevent_t)); 2230 if (newsevent == NULL) 2231 return; 2232 2233 buf = allocate_udp_buffer(disp); 2234 if (buf == NULL) { 2235 isc_event_free(ISC_EVENT_PTR(&newsevent)); 2236 return; 2237 } 2238 memcpy(buf, sevent->region.base, sevent->n); 2239 newsevent->region.base = buf; 2240 newsevent->region.length = disp->mgr->buffersize; 2241 newsevent->n = sevent->n; 2242 newsevent->result = sevent->result; 2243 newsevent->address = sevent->address; 2244 newsevent->timestamp = sevent->timestamp; 2245 newsevent->pktinfo = sevent->pktinfo; 2246 newsevent->attributes = sevent->attributes; 2247 2248 isc_task_send(disp->task, ISC_EVENT_PTR(&newsevent)); 2249} 2250 2251#if 0 2252void 2253dns_dispatchmgr_dump(dns_dispatchmgr_t *mgr) { 2254 dns_dispatch_t *disp; 2255 char foo[1024]; 2256 2257 disp = ISC_LIST_HEAD(mgr->list); 2258 while (disp != NULL) { 2259 isc_sockaddr_format(&disp->local, foo, sizeof(foo)); 2260 printf("\tdispatch %p, addr %s\n", disp, foo); 2261 disp = ISC_LIST_NEXT(disp, link); 2262 } 2263} 2264#endif 2265 2266/* 2267 * Allow the user to pick one of two ID randomization algorithms. 2268 * 2269 * The first algorithm is an adaptation of the sequence shuffling 2270 * algorithm discovered by Carter Bays and S. D. Durham [ACM Trans. Math. 2271 * Software 2 (1976), 59-64], as documented as Algorithm B in Chapter 2272 * 3.2.2 in Volume 2 of Knuth's "The Art of Computer Programming". We use 2273 * a randomly selected linear congruential random number generator with a 2274 * modulus of 2^16, whose increment is a randomly picked odd number, and 2275 * whose multiplier is picked from a set which meets the following 2276 * criteria: 2277 * Is of the form 8*n+5, which ensures "high potency" according to 2278 * principle iii in the summary chapter 3.6. This form also has a 2279 * gcd(a-1,m) of 4 which is good according to principle iv. 2280 * 2281 * Is between 0.01 and 0.99 times the modulus as specified by 2282 * principle iv. 2283 * 2284 * Passes the spectral test "with flying colors" (ut >= 1) in 2285 * dimensions 2 through 6 as calculated by Algorithm S in Chapter 2286 * 3.3.4 and the ratings calculated by formula 35 in section E. 2287 * 2288 * Of the multipliers that pass this test, pick the set that is 2289 * best according to the theoretical bounds of the serial 2290 * correlation test. This was calculated using a simplified 2291 * version of Knuth's Theorem K in Chapter 3.3.3. 2292 * 2293 * These criteria may not be important for this use, but we might as well 2294 * pick from the best generators since there are so many possible ones and 2295 * we don't have that many random bits to do the picking. 2296 * 2297 * We use a modulus of 2^16 instead of something bigger so that we will 2298 * tend to cycle through all the possible IDs before repeating any, 2299 * however the shuffling will perturb this somewhat. Theoretically there 2300 * is no minimimum interval between two uses of the same ID, but in 2301 * practice it seems to be >64000. 2302 * 2303 * Our adaptatation of Algorithm B mixes the hash state which has 2304 * captured various random events into the shuffler to perturb the 2305 * sequence. 2306 * 2307 * One disadvantage of this algorithm is that if the generator parameters 2308 * were to be guessed, it would be possible to mount a limited brute force 2309 * attack on the ID space since the IDs are only shuffled within a limited 2310 * range. 2311 * 2312 * The second algorithm uses the same random number generator to populate 2313 * a pool of 65536 IDs. The hash state is used to pick an ID from a window 2314 * of 4096 IDs in this pool, then the chosen ID is swapped with the ID 2315 * at the beginning of the window and the window position is advanced. 2316 * This means that the interval between uses of the ID will be no less 2317 * than 65536-4096. The ID sequence in the pool will become more random 2318 * over time. 2319 * 2320 * For both algorithms, two more linear congruential random number generators 2321 * are selected. The ID from the first part of algorithm is used to seed 2322 * the first of these generators, and its output is used to seed the second. 2323 * The strategy is use these generators as 1 to 1 hashes to obfuscate the 2324 * properties of the generator used in the first part of either algorithm. 2325 * 2326 * The first algorithm may be suitable for use in a client resolver since 2327 * its memory requirements are fairly low and it's pretty random out of 2328 * the box. It is somewhat succeptible to a limited brute force attack, 2329 * so the second algorithm is probably preferable for a longer running 2330 * program that issues a large number of queries and has time to randomize 2331 * the pool. 2332 */ 2333 2334#define NSID_SHUFFLE_TABLE_SIZE 100 /* Suggested by Knuth */ 2335/* 2336 * Pick one of the next 4096 IDs in the pool. 2337 * There is a tradeoff here between randomness and how often and ID is reused. 2338 */ 2339#define NSID_LOOKAHEAD 4096 /* Must be a power of 2 */ 2340#define NSID_SHUFFLE_ONLY 1 /* algorithm 1 */ 2341#define NSID_USE_POOL 2 /* algorithm 2 */ 2342#define NSID_HASHSHIFT 3 2343#define NSID_HASHROTATE(v) \ 2344 (((v) << NSID_HASHSHIFT) | ((v) >> ((sizeof(v) * 8) - NSID_HASHSHIFT))) 2345 2346static isc_uint32_t nsid_hash_state; 2347 2348/* 2349 * Keep a running hash of various bits of data that we'll use to 2350 * stir the ID pool or perturb the ID generator 2351 */ 2352static void 2353nsid_hash(void *data, size_t len) { 2354 unsigned char *p = data; 2355 /* 2356 * Hash function similar to the one we use for hashing names. 2357 * We don't fold case or toss the upper bit here, though. 2358 * This hash doesn't do much interesting when fed binary zeros, 2359 * so there may be a better hash function. 2360 * This function doesn't need to be very strong since we're 2361 * only using it to stir the pool, but it should be reasonably 2362 * fast. 2363 */ 2364 /* 2365 * We don't care about locking access to nsid_hash_state. 2366 * In fact races make the result even more non deteministic. 2367 */ 2368 while (len-- > 0U) { 2369 nsid_hash_state = NSID_HASHROTATE(nsid_hash_state); 2370 nsid_hash_state += *p++; 2371 } 2372} 2373 2374/* 2375 * Table of good linear congruential multipliers for modulus 2^16 2376 * in order of increasing serial correlation bounds (so trim from 2377 * the end). 2378 */ 2379static const isc_uint16_t nsid_multiplier_table[] = { 2380 17565, 25013, 11733, 19877, 23989, 23997, 24997, 25421, 2381 26781, 27413, 35901, 35917, 35973, 36229, 38317, 38437, 2382 39941, 40493, 41853, 46317, 50581, 51429, 53453, 53805, 2383 11317, 11789, 12045, 12413, 14277, 14821, 14917, 18989, 2384 19821, 23005, 23533, 23573, 23693, 27549, 27709, 28461, 2385 29365, 35605, 37693, 37757, 38309, 41285, 45261, 47061, 2386 47269, 48133, 48597, 50277, 50717, 50757, 50805, 51341, 2387 51413, 51581, 51597, 53445, 11493, 14229, 20365, 20653, 2388 23485, 25541, 27429, 29421, 30173, 35445, 35653, 36789, 2389 36797, 37109, 37157, 37669, 38661, 39773, 40397, 41837, 2390 41877, 45293, 47277, 47845, 49853, 51085, 51349, 54085, 2391 56933, 8877, 8973, 9885, 11365, 11813, 13581, 13589, 2392 13613, 14109, 14317, 15765, 15789, 16925, 17069, 17205, 2393 17621, 17941, 19077, 19381, 20245, 22845, 23733, 24869, 2394 25453, 27213, 28381, 28965, 29245, 29997, 30733, 30901, 2395 34877, 35485, 35613, 36133, 36661, 36917, 38597, 40285, 2396 40693, 41413, 41541, 41637, 42053, 42349, 45245, 45469, 2397 46493, 48205, 48613, 50861, 51861, 52877, 53933, 54397, 2398 55669, 56453, 56965, 58021, 7757, 7781, 8333, 9661, 2399 12229, 14373, 14453, 17549, 18141, 19085, 20773, 23701, 2400 24205, 24333, 25261, 25317, 27181, 30117, 30477, 34757, 2401 34885, 35565, 35885, 36541, 37957, 39733, 39813, 41157, 2402 41893, 42317, 46621, 48117, 48181, 49525, 55261, 55389, 2403 56845, 7045, 7749, 7965, 8469, 9133, 9549, 9789, 2404 10173, 11181, 11285, 12253, 13453, 13533, 13757, 14477, 2405 15053, 16901, 17213, 17269, 17525, 17629, 18605, 19013, 2406 19829, 19933, 20069, 20093, 23261, 23333, 24949, 25309, 2407 27613, 28453, 28709, 29301, 29541, 34165, 34413, 37301, 2408 37773, 38045, 38405, 41077, 41781, 41925, 42717, 44437, 2409 44525, 44613, 45933, 45941, 47077, 50077, 50893, 52117, 2410 5293, 55069, 55989, 58125, 59205, 6869, 14685, 15453, 2411 16821, 17045, 17613, 18437, 21029, 22773, 22909, 25445, 2412 25757, 26541, 30709, 30909, 31093, 31149, 37069, 37725, 2413 37925, 38949, 39637, 39701, 40765, 40861, 42965, 44813, 2414 45077, 45733, 47045, 50093, 52861, 52957, 54181, 56325, 2415 56365, 56381, 56877, 57013, 5741, 58101, 58669, 8613, 2416 10045, 10261, 10653, 10733, 11461, 12261, 14069, 15877, 2417 17757, 21165, 23885, 24701, 26429, 26645, 27925, 28765, 2418 29197, 30189, 31293, 39781, 39909, 40365, 41229, 41453, 2419 41653, 42165, 42365, 47421, 48029, 48085, 52773, 5573, 2420 57037, 57637, 58341, 58357, 58901, 6357, 7789, 9093, 2421 10125, 10709, 10765, 11957, 12469, 13437, 13509, 14773, 2422 15437, 15773, 17813, 18829, 19565, 20237, 23461, 23685, 2423 23725, 23941, 24877, 25461, 26405, 29509, 30285, 35181, 2424 37229, 37893, 38565, 40293, 44189, 44581, 45701, 47381, 2425 47589, 48557, 4941, 51069, 5165, 52797, 53149, 5341, 2426 56301, 56765, 58581, 59493, 59677, 6085, 6349, 8293, 2427 8501, 8517, 11597, 11709, 12589, 12693, 13517, 14909, 2428 17397, 18085, 21101, 21269, 22717, 25237, 25661, 29189, 2429 30101, 31397, 33933, 34213, 34661, 35533, 36493, 37309, 2430 40037, 4189, 42909, 44309, 44357, 44389, 4541, 45461, 2431 46445, 48237, 54149, 55301, 55853, 56621, 56717, 56901, 2432 5813, 58437, 12493, 15365, 15989, 17829, 18229, 19341, 2433 21013, 21357, 22925, 24885, 26053, 27581, 28221, 28485, 2434 30605, 30613, 30789, 35437, 36285, 37189, 3941, 41797, 2435 4269, 42901, 43293, 44645, 45221, 46893, 4893, 50301, 2436 50325, 5189, 52109, 53517, 54053, 54485, 5525, 55949, 2437 56973, 59069, 59421, 60733, 61253, 6421, 6701, 6709, 2438 7101, 8669, 15797, 19221, 19837, 20133, 20957, 21293, 2439 21461, 22461, 29085, 29861, 30869, 34973, 36469, 37565, 2440 38125, 38829, 39469, 40061, 40117, 44093, 47429, 48341, 2441 50597, 51757, 5541, 57629, 58405, 59621, 59693, 59701, 2442 61837, 7061, 10421, 11949, 15405, 20861, 25397, 25509, 2443 25893, 26037, 28629, 28869, 29605, 30213, 34205, 35637, 2444 36365, 37285, 3773, 39117, 4021, 41061, 42653, 44509, 2445 4461, 44829, 4725, 5125, 52269, 56469, 59085, 5917, 2446 60973, 8349, 17725, 18637, 19773, 20293, 21453, 22533, 2447 24285, 26333, 26997, 31501, 34541, 34805, 37509, 38477, 2448 41333, 44125, 46285, 46997, 47637, 48173, 4925, 50253, 2449 50381, 50917, 51205, 51325, 52165, 52229, 5253, 5269, 2450 53509, 56253, 56341, 5821, 58373, 60301, 61653, 61973, 2451 62373, 8397, 11981, 14341, 14509, 15077, 22261, 22429, 2452 24261, 28165, 28685, 30661, 34021, 34445, 39149, 3917, 2453 43013, 43317, 44053, 44101, 4533, 49541, 49981, 5277, 2454 54477, 56357, 57261, 57765, 58573, 59061, 60197, 61197, 2455 62189, 7725, 8477, 9565, 10229, 11437, 14613, 14709, 2456 16813, 20029, 20677, 31445, 3165, 31957, 3229, 33541, 2457 36645, 3805, 38973, 3965, 4029, 44293, 44557, 46245, 2458 48917, 4909, 51749, 53709, 55733, 56445, 5925, 6093, 2459 61053, 62637, 8661, 9109, 10821, 11389, 13813, 14325, 2460 15501, 16149, 18845, 22669, 26437, 29869, 31837, 33709, 2461 33973, 34173, 3677, 3877, 3981, 39885, 42117, 4421, 2462 44221, 44245, 44693, 46157, 47309, 5005, 51461, 52037, 2463 55333, 55693, 56277, 58949, 6205, 62141, 62469, 6293, 2464 10101, 12509, 14029, 17997, 20469, 21149, 25221, 27109, 2465 2773, 2877, 29405, 31493, 31645, 4077, 42005, 42077, 2466 42469, 42501, 44013, 48653, 49349, 4997, 50101, 55405, 2467 56957, 58037, 59429, 60749, 61797, 62381, 62837, 6605, 2468 10541, 23981, 24533, 2701, 27333, 27341, 31197, 33805, 2469 3621, 37381, 3749, 3829, 38533, 42613, 44381, 45901, 2470 48517, 51269, 57725, 59461, 60045, 62029, 13805, 14013, 2471 15461, 16069, 16157, 18573, 2309, 23501, 28645, 3077, 2472 31541, 36357, 36877, 3789, 39429, 39805, 47685, 47949, 2473 49413, 5485, 56757, 57549, 57805, 58317, 59549, 62213, 2474 62613, 62853, 62933, 8909, 12941, 16677, 20333, 21541, 2475 24429, 26077, 26421, 2885, 31269, 33381, 3661, 40925, 2476 42925, 45173, 4525, 4709, 53133, 55941, 57413, 57797, 2477 62125, 62237, 62733, 6773, 12317, 13197, 16533, 16933, 2478 18245, 2213, 2477, 29757, 33293, 35517, 40133, 40749, 2479 4661, 49941, 62757, 7853, 8149, 8573, 11029, 13421, 2480 21549, 22709, 22725, 24629, 2469, 26125, 2669, 34253, 2481 36709, 41013, 45597, 46637, 52285, 52333, 54685, 59013, 2482 60997, 61189, 61981, 62605, 62821, 7077, 7525, 8781, 2483 10861, 15277, 2205, 22077, 28517, 28949, 32109, 33493, 2484 4661, 49941, 62757, 7853, 8149, 8573, 11029, 13421, 2485 21549, 22709, 22725, 24629, 2469, 26125, 2669, 34253, 2486 36709, 41013, 45597, 46637, 52285, 52333, 54685, 59013, 2487 60997, 61189, 61981, 62605, 62821, 7077, 7525, 8781, 2488 10861, 15277, 2205, 22077, 28517, 28949, 32109, 33493, 2489 3685, 39197, 39869, 42621, 44997, 48565, 5221, 57381, 2490 61749, 62317, 63245, 63381, 23149, 2549, 28661, 31653, 2491 33885, 36341, 37053, 39517, 42805, 45853, 48997, 59349, 2492 60053, 62509, 63069, 6525, 1893, 20181, 2365, 24893, 2493 27397, 31357, 32277, 33357, 34437, 36677, 37661, 43469, 2494 43917, 50997, 53869, 5653, 13221, 16741, 17893, 2157, 2495 28653, 31789, 35301, 35821, 61613, 62245, 12405, 14517, 2496 17453, 18421, 3149, 3205, 40341, 4109, 43941, 46869, 2497 48837, 50621, 57405, 60509, 62877, 8157, 12933, 12957, 2498 16501, 19533, 3461, 36829, 52357, 58189, 58293, 63053, 2499 17109, 1933, 32157, 37701, 59005, 61621, 13029, 15085, 2500 16493, 32317, 35093, 5061, 51557, 62221, 20765, 24613, 2501 2629, 30861, 33197, 33749, 35365, 37933, 40317, 48045, 2502 56229, 61157, 63797, 7917, 17965, 1917, 1973, 20301, 2503 2253, 33157, 58629, 59861, 61085, 63909, 8141, 9221, 2504 14757, 1581, 21637, 26557, 33869, 34285, 35733, 40933, 2505 42517, 43501, 53653, 61885, 63805, 7141, 21653, 54973, 2506 31189, 60061, 60341, 63357, 16045, 2053, 26069, 33997, 2507 43901, 54565, 63837, 8949, 17909, 18693, 32349, 33125, 2508 37293, 48821, 49053, 51309, 64037, 7117, 1445, 20405, 2509 23085, 26269, 26293, 27349, 32381, 33141, 34525, 36461, 2510 37581, 43525, 4357, 43877, 5069, 55197, 63965, 9845, 2511 12093, 2197, 2229, 32165, 33469, 40981, 42397, 8749, 2512 10853, 1453, 18069, 21693, 30573, 36261, 37421, 42533 2513}; 2514 2515#define NSID_MULT_TABLE_SIZE \ 2516 ((sizeof nsid_multiplier_table)/(sizeof nsid_multiplier_table[0])) 2517#define NSID_RANGE_MASK (NSID_LOOKAHEAD - 1) 2518#define NSID_POOL_MASK 0xFFFF /* used to wrap the pool index */ 2519#define NSID_SHUFFLE_ONLY 1 2520#define NSID_USE_POOL 2 2521 2522static isc_uint16_t 2523nsid_next(dns_nsid_t *nsid) { 2524 isc_uint16_t id, compressed_hash; 2525 isc_uint16_t j; 2526 2527 compressed_hash = ((nsid_hash_state >> 16) ^ 2528 (nsid_hash_state)) & 0xFFFF; 2529 2530 if (nsid->nsid_usepool) { 2531 isc_uint16_t pick; 2532 2533 pick = compressed_hash & NSID_RANGE_MASK; 2534 pick = (nsid->nsid_state + pick) & NSID_POOL_MASK; 2535 id = nsid->nsid_pool[pick]; 2536 if (pick != 0) { 2537 /* Swap two IDs to stir the pool */ 2538 nsid->nsid_pool[pick] = 2539 nsid->nsid_pool[nsid->nsid_state]; 2540 nsid->nsid_pool[nsid->nsid_state] = id; 2541 } 2542 2543 /* increment the base pointer into the pool */ 2544 if (nsid->nsid_state == 65535) 2545 nsid->nsid_state = 0; 2546 else 2547 nsid->nsid_state++; 2548 } else { 2549 /* 2550 * This is the original Algorithm B 2551 * j = ((u_long) NSID_SHUFFLE_TABLE_SIZE * nsid_state2) >> 16; 2552 * 2553 * We'll perturb it with some random stuff ... 2554 */ 2555 j = ((isc_uint32_t) NSID_SHUFFLE_TABLE_SIZE * 2556 (nsid->nsid_state2 ^ compressed_hash)) >> 16; 2557 nsid->nsid_state2 = id = nsid->nsid_vtable[j]; 2558 nsid->nsid_state = (((isc_uint32_t) nsid->nsid_a1 * nsid->nsid_state) + 2559 nsid->nsid_c1) & 0xFFFF; 2560 nsid->nsid_vtable[j] = nsid->nsid_state; 2561 } 2562 2563 /* Now lets obfuscate ... */ 2564 id = (((isc_uint32_t) nsid->nsid_a2 * id) + nsid->nsid_c2) & 0xFFFF; 2565 id = (((isc_uint32_t) nsid->nsid_a3 * id) + nsid->nsid_c3) & 0xFFFF; 2566 2567 return (id); 2568} 2569 2570static isc_result_t 2571nsid_init(isc_mem_t *mctx, dns_nsid_t *nsid, isc_boolean_t usepool) { 2572 isc_time_t now; 2573 pid_t mypid; 2574 isc_uint16_t a1ndx, a2ndx, a3ndx, c1ndx, c2ndx, c3ndx; 2575 int i; 2576 2577 isc_time_now(&now); 2578 mypid = getpid(); 2579 2580 /* Initialize the state */ 2581 memset(nsid, 0, sizeof(*nsid)); 2582 nsid_hash(&now, sizeof now); 2583 nsid_hash(&mypid, sizeof mypid); 2584 2585 /* 2586 * Select our random number generators and initial seed. 2587 * We could really use more random bits at this point, 2588 * but we'll try to make a silk purse out of a sows ear ... 2589 */ 2590 /* generator 1 */ 2591 a1ndx = ((isc_uint32_t) NSID_MULT_TABLE_SIZE * 2592 (nsid_hash_state & 0xFFFF)) >> 16; 2593 nsid->nsid_a1 = nsid_multiplier_table[a1ndx]; 2594 c1ndx = (nsid_hash_state >> 9) & 0x7FFF; 2595 nsid->nsid_c1 = 2 * c1ndx + 1; 2596 2597 /* generator 2, distinct from 1 */ 2598 a2ndx = ((isc_uint32_t) (NSID_MULT_TABLE_SIZE - 1) * 2599 ((nsid_hash_state >> 10) & 0xFFFF)) >> 16; 2600 if (a2ndx >= a1ndx) 2601 a2ndx++; 2602 nsid->nsid_a2 = nsid_multiplier_table[a2ndx]; 2603 c2ndx = nsid_hash_state % 32767; 2604 if (c2ndx >= c1ndx) 2605 c2ndx++; 2606 nsid->nsid_c2 = 2*c2ndx + 1; 2607 2608 /* generator 3, distinct from 1 and 2 */ 2609 a3ndx = ((isc_uint32_t) (NSID_MULT_TABLE_SIZE - 2) * 2610 ((nsid_hash_state >> 20) & 0xFFFF)) >> 16; 2611 if (a3ndx >= a1ndx || a3ndx >= a2ndx) 2612 a3ndx++; 2613 if (a3ndx >= a1ndx && a3ndx >= a2ndx) 2614 a3ndx++; 2615 nsid->nsid_a3 = nsid_multiplier_table[a3ndx]; 2616 c3ndx = nsid_hash_state % 32766; 2617 if (c3ndx >= c1ndx || c3ndx >= c2ndx) 2618 c3ndx++; 2619 if (c3ndx >= c1ndx && c3ndx >= c2ndx) 2620 c3ndx++; 2621 nsid->nsid_c3 = 2*c3ndx + 1; 2622 2623 nsid->nsid_state = 2624 ((nsid_hash_state >> 16) ^ (nsid_hash_state)) & 0xFFFF; 2625 2626 nsid->nsid_usepool = usepool; 2627 if (nsid->nsid_usepool) { 2628 nsid->nsid_pool = isc_mem_get(mctx, 0x10000 * sizeof(isc_uint16_t)); 2629 if (nsid->nsid_pool == NULL) 2630 return (ISC_R_NOMEMORY); 2631 for (i = 0; ; i++) { 2632 nsid->nsid_pool[i] = nsid->nsid_state; 2633 nsid->nsid_state = 2634 (((u_long) nsid->nsid_a1 * nsid->nsid_state) + 2635 nsid->nsid_c1) & 0xFFFF; 2636 if (i == 0xFFFF) 2637 break; 2638 } 2639 } else { 2640 nsid->nsid_vtable = isc_mem_get(mctx, NSID_SHUFFLE_TABLE_SIZE * 2641 (sizeof(isc_uint16_t)) ); 2642 if (nsid->nsid_vtable == NULL) 2643 return (ISC_R_NOMEMORY); 2644 2645 for (i = 0; i < NSID_SHUFFLE_TABLE_SIZE; i++) { 2646 nsid->nsid_vtable[i] = nsid->nsid_state; 2647 nsid->nsid_state = 2648 (((isc_uint32_t) nsid->nsid_a1 * nsid->nsid_state) + 2649 nsid->nsid_c1) & 0xFFFF; 2650 } 2651 nsid->nsid_state2 = nsid->nsid_state; 2652 } 2653 return (ISC_R_SUCCESS); 2654} 2655 2656static void 2657nsid_destroy(isc_mem_t *mctx, dns_nsid_t *nsid) { 2658 if (nsid->nsid_usepool) 2659 isc_mem_put(mctx, nsid->nsid_pool, 2660 0x10000 * sizeof(isc_uint16_t)); 2661 else 2662 isc_mem_put(mctx, nsid->nsid_vtable, 2663 NSID_SHUFFLE_TABLE_SIZE * (sizeof(isc_uint16_t)) ); 2664 memset(nsid, 0, sizeof(*nsid)); 2665} 2666 2667void 2668dns_dispatch_hash(void *data, size_t len) { 2669 nsid_hash(data, len); 2670} 2671