1 /* $NetBSD: dispatch.h,v 1.8 2015/07/08 17:28:59 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* Id: dispatch.h,v 1.64 2011/07/28 23:47:58 tbox Exp */ 21 22 #ifndef DNS_DISPATCH_H 23 #define DNS_DISPATCH_H 1 24 25 /***** 26 ***** Module Info 27 *****/ 28 29 /*! \file dns/dispatch.h 30 * \brief 31 * DNS Dispatch Management 32 * Shared UDP and single-use TCP dispatches for queries and responses. 33 * 34 * MP: 35 * 36 *\li All locking is performed internally to each dispatch. 37 * Restrictions apply to dns_dispatch_removeresponse(). 38 * 39 * Reliability: 40 * 41 * Resources: 42 * 43 * Security: 44 * 45 *\li Depends on the isc_socket_t and dns_message_t for prevention of 46 * buffer overruns. 47 * 48 * Standards: 49 * 50 *\li None. 51 */ 52 53 /*** 54 *** Imports 55 ***/ 56 57 #include <isc/buffer.h> 58 #include <isc/lang.h> 59 #include <isc/mutex.h> 60 #include <isc/socket.h> 61 #include <isc/types.h> 62 63 #include <dns/types.h> 64 65 ISC_LANG_BEGINDECLS 66 67 /*% 68 * This event is sent to a task when a response comes in. 69 * No part of this structure should ever be modified by the caller, 70 * other than parts of the buffer. The holy parts of the buffer are 71 * the base and size of the buffer. All other parts of the buffer may 72 * be used. On event delivery the used region contains the packet. 73 * 74 * "id" is the received message id, 75 * 76 * "addr" is the host that sent it to us, 77 * 78 * "buffer" holds state on the received data. 79 * 80 * The "free" routine for this event will clean up itself as well as 81 * any buffer space allocated from common pools. 82 */ 83 84 struct dns_dispatchevent { 85 ISC_EVENT_COMMON(dns_dispatchevent_t); /*%< standard event common */ 86 isc_result_t result; /*%< result code */ 87 isc_int32_t id; /*%< message id */ 88 isc_sockaddr_t addr; /*%< address recv'd from */ 89 struct in6_pktinfo pktinfo; /*%< reply info for v6 */ 90 isc_buffer_t buffer; /*%< data buffer */ 91 isc_uint32_t attributes; /*%< mirrored from socket.h */ 92 }; 93 94 /*% 95 * This is a set of one or more dispatches which can be retrieved 96 * round-robin fashion. 97 */ 98 struct dns_dispatchset { 99 isc_mem_t *mctx; 100 dns_dispatch_t **dispatches; 101 int ndisp; 102 int cur; 103 isc_mutex_t lock; 104 }; 105 106 /*@{*/ 107 /*% 108 * Attributes for added dispatchers. 109 * 110 * Values with the mask 0xffff0000 are application defined. 111 * Values with the mask 0x0000ffff are library defined. 112 * 113 * Insane values (like setting both TCP and UDP) are not caught. Don't 114 * do that. 115 * 116 * _PRIVATE 117 * The dispatcher cannot be shared. 118 * 119 * _TCP, _UDP 120 * The dispatcher is a TCP or UDP socket. 121 * 122 * _IPV4, _IPV6 123 * The dispatcher uses an IPv4 or IPv6 socket. 124 * 125 * _NOLISTEN 126 * The dispatcher should not listen on the socket. 127 * 128 * _MAKEQUERY 129 * The dispatcher can be used to issue queries to other servers, and 130 * accept replies from them. 131 * 132 * _RANDOMPORT 133 * Previously used to indicate that the port of a dispatch UDP must be 134 * chosen randomly. This behavior now always applies and the attribute 135 * is obsoleted. 136 * 137 * _EXCLUSIVE 138 * A separate socket will be used on-demand for each transaction. 139 */ 140 #define DNS_DISPATCHATTR_PRIVATE 0x00000001U 141 #define DNS_DISPATCHATTR_TCP 0x00000002U 142 #define DNS_DISPATCHATTR_UDP 0x00000004U 143 #define DNS_DISPATCHATTR_IPV4 0x00000008U 144 #define DNS_DISPATCHATTR_IPV6 0x00000010U 145 #define DNS_DISPATCHATTR_NOLISTEN 0x00000020U 146 #define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U 147 #define DNS_DISPATCHATTR_CONNECTED 0x00000080U 148 #define DNS_DISPATCHATTR_FIXEDID 0x00000100U 149 #define DNS_DISPATCHATTR_EXCLUSIVE 0x00000200U 150 /*@}*/ 151 152 /* 153 */ 154 #define DNS_DISPATCHOPT_FIXEDID 0x00000001U 155 156 isc_result_t 157 dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, 158 dns_dispatchmgr_t **mgrp); 159 /*%< 160 * Creates a new dispatchmgr object. 161 * 162 * Requires: 163 *\li "mctx" be a valid memory context. 164 * 165 *\li mgrp != NULL && *mgrp == NULL 166 * 167 *\li "entropy" may be NULL, in which case an insecure random generator 168 * will be used. If it is non-NULL, it must be a valid entropy 169 * source. 170 * 171 * Returns: 172 *\li ISC_R_SUCCESS -- all ok 173 * 174 *\li anything else -- failure 175 */ 176 177 178 void 179 dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp); 180 /*%< 181 * Destroys the dispatchmgr when it becomes empty. This could be 182 * immediately. 183 * 184 * Requires: 185 *\li mgrp != NULL && *mgrp is a valid dispatchmgr. 186 */ 187 188 189 void 190 dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole); 191 /*%< 192 * Sets the dispatcher's "blackhole list," a list of addresses that will 193 * be ignored by all dispatchers created by the dispatchmgr. 194 * 195 * Requires: 196 * \li mgrp is a valid dispatchmgr 197 * \li blackhole is a valid acl 198 */ 199 200 201 dns_acl_t * 202 dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr); 203 /*%< 204 * Gets a pointer to the dispatcher's current blackhole list, 205 * without incrementing its reference count. 206 * 207 * Requires: 208 *\li mgr is a valid dispatchmgr 209 * Returns: 210 *\li A pointer to the current blackhole list, or NULL. 211 */ 212 213 void 214 dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr, 215 dns_portlist_t *portlist); 216 /*%< 217 * This function is deprecated. Use dns_dispatchmgr_setavailports() instead. 218 * 219 * Requires: 220 *\li mgr is a valid dispatchmgr 221 */ 222 223 dns_portlist_t * 224 dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr); 225 /*%< 226 * This function is deprecated and always returns NULL. 227 * 228 * Requires: 229 *\li mgr is a valid dispatchmgr 230 */ 231 232 isc_result_t 233 dns_dispatchmgr_setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset, 234 isc_portset_t *v6portset); 235 /*%< 236 * Sets a list of UDP ports that can be used for outgoing UDP messages. 237 * 238 * Requires: 239 *\li mgr is a valid dispatchmgr 240 *\li v4portset is NULL or a valid port set 241 *\li v6portset is NULL or a valid port set 242 */ 243 244 void 245 dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats); 246 /*%< 247 * Sets statistics counter for the dispatchmgr. This function is expected to 248 * be called only on zone creation (when necessary). 249 * Once installed, it cannot be removed or replaced. Also, there is no 250 * interface to get the installed stats from the zone; the caller must keep the 251 * stats to reference (e.g. dump) it later. 252 * 253 * Requires: 254 *\li mgr is a valid dispatchmgr with no managed dispatch. 255 *\li stats is a valid statistics supporting resolver statistics counters 256 * (see dns/stats.h). 257 */ 258 259 isc_result_t 260 dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, 261 isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, 262 unsigned int buffersize, 263 unsigned int maxbuffers, unsigned int maxrequests, 264 unsigned int buckets, unsigned int increment, 265 unsigned int attributes, unsigned int mask, 266 dns_dispatch_t **dispp); 267 268 isc_result_t 269 dns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, 270 isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, 271 unsigned int buffersize, 272 unsigned int maxbuffers, unsigned int maxrequests, 273 unsigned int buckets, unsigned int increment, 274 unsigned int attributes, unsigned int mask, 275 dns_dispatch_t **dispp, dns_dispatch_t *dup); 276 /*%< 277 * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find, 278 * otherwise create a new UDP dispatch. 279 * 280 * Requires: 281 *\li All pointer parameters be valid for their respective types. 282 * 283 *\li dispp != NULL && *disp == NULL 284 * 285 *\li 512 <= buffersize <= 64k 286 * 287 *\li maxbuffers > 0 288 * 289 *\li buckets < 2097169 290 * 291 *\li increment > buckets 292 * 293 *\li (attributes & DNS_DISPATCHATTR_TCP) == 0 294 * 295 * Returns: 296 *\li ISC_R_SUCCESS -- success. 297 * 298 *\li Anything else -- failure. 299 */ 300 301 isc_result_t 302 dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, 303 isc_taskmgr_t *taskmgr, unsigned int buffersize, 304 unsigned int maxbuffers, unsigned int maxrequests, 305 unsigned int buckets, unsigned int increment, 306 unsigned int attributes, dns_dispatch_t **dispp); 307 /*%< 308 * Create a new dns_dispatch and attach it to the provided isc_socket_t. 309 * 310 * For all dispatches, "buffersize" is the maximum packet size we will 311 * accept. 312 * 313 * "maxbuffers" and "maxrequests" control the number of buffers in the 314 * overall system and the number of buffers which can be allocated to 315 * requests. 316 * 317 * "buckets" is the number of buckets to use, and should be prime. 318 * 319 * "increment" is used in a collision avoidance function, and needs to be 320 * a prime > buckets, and not 2. 321 * 322 * Requires: 323 * 324 *\li mgr is a valid dispatch manager. 325 * 326 *\li sock is a valid. 327 * 328 *\li task is a valid task that can be used internally to this dispatcher. 329 * 330 * \li 512 <= buffersize <= 64k 331 * 332 *\li maxbuffers > 0. 333 * 334 *\li maxrequests <= maxbuffers. 335 * 336 *\li buckets < 2097169 (the next prime after 65536 * 32) 337 * 338 *\li increment > buckets (and prime). 339 * 340 *\li attributes includes #DNS_DISPATCHATTR_TCP and does not include 341 * #DNS_DISPATCHATTR_UDP. 342 * 343 * Returns: 344 *\li ISC_R_SUCCESS -- success. 345 * 346 *\li Anything else -- failure. 347 */ 348 349 void 350 dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp); 351 /*%< 352 * Attach to a dispatch handle. 353 * 354 * Requires: 355 *\li disp is valid. 356 * 357 *\li dispp != NULL && *dispp == NULL 358 */ 359 360 void 361 dns_dispatch_detach(dns_dispatch_t **dispp); 362 /*%< 363 * Detaches from the dispatch. 364 * 365 * Requires: 366 *\li dispp != NULL and *dispp be a valid dispatch. 367 */ 368 369 void 370 dns_dispatch_starttcp(dns_dispatch_t *disp); 371 /*%< 372 * Start processing of a TCP dispatch once the socket connects. 373 * 374 * Requires: 375 *\li 'disp' is valid. 376 */ 377 378 isc_result_t 379 dns_dispatch_addresponse3(dns_dispatch_t *disp, unsigned int options, 380 isc_sockaddr_t *dest, isc_task_t *task, 381 isc_taskaction_t action, void *arg, 382 isc_uint16_t *idp, dns_dispentry_t **resp, 383 isc_socketmgr_t *sockmgr); 384 385 isc_result_t 386 dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest, 387 isc_task_t *task, isc_taskaction_t action, void *arg, 388 isc_uint16_t *idp, dns_dispentry_t **resp, 389 isc_socketmgr_t *sockmgr); 390 391 isc_result_t 392 dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest, 393 isc_task_t *task, isc_taskaction_t action, void *arg, 394 isc_uint16_t *idp, dns_dispentry_t **resp); 395 /*%< 396 * Add a response entry for this dispatch. 397 * 398 * "*idp" is filled in with the assigned message ID, and *resp is filled in 399 * to contain the magic token used to request event flow stop. 400 * 401 * Arranges for the given task to get a callback for response packets. When 402 * the event is delivered, it must be returned using dns_dispatch_freeevent() 403 * or through dns_dispatch_removeresponse() for another to be delivered. 404 * 405 * Requires: 406 *\li "idp" be non-NULL. 407 * 408 *\li "task" "action" and "arg" be set as appropriate. 409 * 410 *\li "dest" be non-NULL and valid. 411 * 412 *\li "resp" be non-NULL and *resp be NULL 413 * 414 *\li "sockmgr" be NULL or a valid socket manager. If 'disp' has 415 * the DNS_DISPATCHATTR_EXCLUSIVE attribute, this must not be NULL, 416 * which also means dns_dispatch_addresponse() cannot be used. 417 * 418 * Ensures: 419 * 420 *\li <id, dest> is a unique tuple. That means incoming messages 421 * are identifiable. 422 * 423 * Returns: 424 * 425 *\li ISC_R_SUCCESS -- all is well. 426 *\li ISC_R_NOMEMORY -- memory could not be allocated. 427 *\li ISC_R_NOMORE -- no more message ids can be allocated 428 * for this destination. 429 */ 430 431 432 void 433 dns_dispatch_removeresponse(dns_dispentry_t **resp, 434 dns_dispatchevent_t **sockevent); 435 /*%< 436 * Stops the flow of responses for the provided id and destination. 437 * If "sockevent" is non-NULL, the dispatch event and associated buffer is 438 * also returned to the system. 439 * 440 * Requires: 441 *\li "resp" != NULL and "*resp" contain a value previously allocated 442 * by dns_dispatch_addresponse(); 443 * 444 *\li May only be called from within the task given as the 'task' 445 * argument to dns_dispatch_addresponse() when allocating '*resp'. 446 */ 447 448 isc_socket_t * 449 dns_dispatch_getentrysocket(dns_dispentry_t *resp); 450 451 isc_socket_t * 452 dns_dispatch_getsocket(dns_dispatch_t *disp); 453 /*%< 454 * Return the socket associated with this dispatcher. 455 * 456 * Requires: 457 *\li disp is valid. 458 * 459 * Returns: 460 *\li The socket the dispatcher is using. 461 */ 462 463 isc_result_t 464 dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp); 465 /*%< 466 * Return the local address for this dispatch. 467 * This currently only works for dispatches using UDP sockets. 468 * 469 * Requires: 470 *\li disp is valid. 471 *\li addrp to be non null. 472 * 473 * Returns: 474 *\li ISC_R_SUCCESS 475 *\li ISC_R_NOTIMPLEMENTED 476 */ 477 478 void 479 dns_dispatch_cancel(dns_dispatch_t *disp); 480 /*%< 481 * cancel outstanding clients 482 * 483 * Requires: 484 *\li disp is valid. 485 */ 486 487 unsigned int 488 dns_dispatch_getattributes(dns_dispatch_t *disp); 489 /*%< 490 * Return the attributes (DNS_DISPATCHATTR_xxx) of this dispatch. Only the 491 * non-changeable attributes are expected to be referenced by the caller. 492 * 493 * Requires: 494 *\li disp is valid. 495 */ 496 497 void 498 dns_dispatch_changeattributes(dns_dispatch_t *disp, 499 unsigned int attributes, unsigned int mask); 500 /*%< 501 * Set the bits described by "mask" to the corresponding values in 502 * "attributes". 503 * 504 * That is: 505 * 506 * \code 507 * new = (old & ~mask) | (attributes & mask) 508 * \endcode 509 * 510 * This function has a side effect when #DNS_DISPATCHATTR_NOLISTEN changes. 511 * When the flag becomes off, the dispatch will start receiving on the 512 * corresponding socket. When the flag becomes on, receive events on the 513 * corresponding socket will be canceled. 514 * 515 * Requires: 516 *\li disp is valid. 517 * 518 *\li attributes are reasonable for the dispatch. That is, setting the UDP 519 * attribute on a TCP socket isn't reasonable. 520 */ 521 522 void 523 dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event); 524 /*%< 525 * Inform the dispatcher of a socket receive. This is used for sockets 526 * shared between dispatchers and clients. If the dispatcher fails to copy 527 * or send the event, nothing happens. 528 * 529 * Requires: 530 *\li disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set. 531 * event != NULL 532 */ 533 534 dns_dispatch_t * 535 dns_dispatchset_get(dns_dispatchset_t *dset); 536 /*%< 537 * Retrieve the next dispatch from dispatch set 'dset', and increment 538 * the round-robin counter. 539 * 540 * Requires: 541 *\li dset != NULL 542 */ 543 544 isc_result_t 545 dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr, 546 isc_taskmgr_t *taskmgr, dns_dispatch_t *source, 547 dns_dispatchset_t **dsetp, int n); 548 /*%< 549 * Given a valid dispatch 'source', create a dispatch set containing 550 * 'n' UDP dispatches, with the remainder filled out by clones of the 551 * source. 552 * 553 * Requires: 554 *\li source is a valid UDP dispatcher 555 *\li dsetp != NULL, *dsetp == NULL 556 */ 557 558 void 559 dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task); 560 /*%< 561 * Cancel socket operations for the dispatches in 'dset'. 562 */ 563 564 void 565 dns_dispatchset_destroy(dns_dispatchset_t **dsetp); 566 /*%< 567 * Dereference all the dispatches in '*dsetp', free the dispatchset 568 * memory, and set *dsetp to NULL. 569 * 570 * Requires: 571 *\li dset is valid 572 */ 573 574 void 575 dns_dispatch_setdscp(dns_dispatch_t *disp, isc_dscp_t dscp); 576 isc_dscp_t 577 dns_dispatch_getdscp(dns_dispatch_t *disp); 578 /*%< 579 * Set/get the DSCP value to be used when sending responses to clients, 580 * as defined in the "listen-on" or "listen-on-v6" statements. 581 * 582 * Requires: 583 *\li disp is valid. 584 */ 585 586 ISC_LANG_ENDDECLS 587 588 #endif /* DNS_DISPATCH_H */ 589