00001 /* 00002 * Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") 00003 * Copyright (C) 1999-2003 Internet Software Consortium. 00004 * 00005 * Permission to use, copy, modify, and/or distribute this software for any 00006 * purpose with or without fee is hereby granted, provided that the above 00007 * copyright notice and this permission notice appear in all copies. 00008 * 00009 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 00010 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 00011 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 00012 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 00013 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 00014 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00015 * PERFORMANCE OF THIS SOFTWARE. 00016 */ 00017 00018 #ifndef DNS_DISPATCH_H 00019 #define DNS_DISPATCH_H 1 00020 00021 /***** 00022 ***** Module Info 00023 *****/ 00024 00025 /*! \file dns/dispatch.h 00026 * \brief 00027 * DNS Dispatch Management 00028 * Shared UDP and single-use TCP dispatches for queries and responses. 00029 * 00030 * MP: 00031 * 00032 *\li All locking is performed internally to each dispatch. 00033 * Restrictions apply to dns_dispatch_removeresponse(). 00034 * 00035 * Reliability: 00036 * 00037 * Resources: 00038 * 00039 * Security: 00040 * 00041 *\li Depends on the isc_socket_t and dns_message_t for prevention of 00042 * buffer overruns. 00043 * 00044 * Standards: 00045 * 00046 *\li None. 00047 */ 00048 00049 /*** 00050 *** Imports 00051 ***/ 00052 00053 #include <isc/buffer.h> 00054 #include <isc/lang.h> 00055 #include <isc/mutex.h> 00056 #include <isc/socket.h> 00057 #include <isc/types.h> 00058 00059 #include <dns/types.h> 00060 00061 ISC_LANG_BEGINDECLS 00062 00063 /*% 00064 * This event is sent to a task when a response comes in. 00065 * No part of this structure should ever be modified by the caller, 00066 * other than parts of the buffer. The holy parts of the buffer are 00067 * the base and size of the buffer. All other parts of the buffer may 00068 * be used. On event delivery the used region contains the packet. 00069 * 00070 * "id" is the received message id, 00071 * 00072 * "addr" is the host that sent it to us, 00073 * 00074 * "buffer" holds state on the received data. 00075 * 00076 * The "free" routine for this event will clean up itself as well as 00077 * any buffer space allocated from common pools. 00078 */ 00079 00080 struct dns_dispatchevent { 00081 ISC_EVENT_COMMON(dns_dispatchevent_t); /*%< standard event common */ 00082 isc_result_t result; /*%< result code */ 00083 isc_int32_t id; /*%< message id */ 00084 isc_sockaddr_t addr; /*%< address recv'd from */ 00085 struct in6_pktinfo pktinfo; /*%< reply info for v6 */ 00086 isc_buffer_t buffer; /*%< data buffer */ 00087 isc_uint32_t attributes; /*%< mirrored from socket.h */ 00088 }; 00089 00090 /*% 00091 * This is a set of one or more dispatches which can be retrieved 00092 * round-robin fashion. 00093 */ 00094 struct dns_dispatchset { 00095 isc_mem_t *mctx; 00096 dns_dispatch_t **dispatches; 00097 int ndisp; 00098 int cur; 00099 isc_mutex_t lock; 00100 }; 00101 00102 /*@{*/ 00103 /*% 00104 * Attributes for added dispatchers. 00105 * 00106 * Values with the mask 0xffff0000 are application defined. 00107 * Values with the mask 0x0000ffff are library defined. 00108 * 00109 * Insane values (like setting both TCP and UDP) are not caught. Don't 00110 * do that. 00111 * 00112 * _PRIVATE 00113 * The dispatcher cannot be shared. 00114 * 00115 * _TCP, _UDP 00116 * The dispatcher is a TCP or UDP socket. 00117 * 00118 * _IPV4, _IPV6 00119 * The dispatcher uses an IPv4 or IPv6 socket. 00120 * 00121 * _NOLISTEN 00122 * The dispatcher should not listen on the socket. 00123 * 00124 * _MAKEQUERY 00125 * The dispatcher can be used to issue queries to other servers, and 00126 * accept replies from them. 00127 * 00128 * _RANDOMPORT 00129 * Previously used to indicate that the port of a dispatch UDP must be 00130 * chosen randomly. This behavior now always applies and the attribute 00131 * is obsoleted. 00132 * 00133 * _EXCLUSIVE 00134 * A separate socket will be used on-demand for each transaction. 00135 */ 00136 #define DNS_DISPATCHATTR_PRIVATE 0x00000001U 00137 #define DNS_DISPATCHATTR_TCP 0x00000002U 00138 #define DNS_DISPATCHATTR_UDP 0x00000004U 00139 #define DNS_DISPATCHATTR_IPV4 0x00000008U 00140 #define DNS_DISPATCHATTR_IPV6 0x00000010U 00141 #define DNS_DISPATCHATTR_NOLISTEN 0x00000020U 00142 #define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U 00143 #define DNS_DISPATCHATTR_CONNECTED 0x00000080U 00144 #define DNS_DISPATCHATTR_FIXEDID 0x00000100U 00145 #define DNS_DISPATCHATTR_EXCLUSIVE 0x00000200U 00146 /*@}*/ 00147 00148 /* 00149 */ 00150 #define DNS_DISPATCHOPT_FIXEDID 0x00000001U 00151 00152 isc_result_t 00153 dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy, 00154 dns_dispatchmgr_t **mgrp); 00155 /*%< 00156 * Creates a new dispatchmgr object. 00157 * 00158 * Requires: 00159 *\li "mctx" be a valid memory context. 00160 * 00161 *\li mgrp != NULL && *mgrp == NULL 00162 * 00163 *\li "entropy" may be NULL, in which case an insecure random generator 00164 * will be used. If it is non-NULL, it must be a valid entropy 00165 * source. 00166 * 00167 * Returns: 00168 *\li ISC_R_SUCCESS -- all ok 00169 * 00170 *\li anything else -- failure 00171 */ 00172 00173 00174 void 00175 dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp); 00176 /*%< 00177 * Destroys the dispatchmgr when it becomes empty. This could be 00178 * immediately. 00179 * 00180 * Requires: 00181 *\li mgrp != NULL && *mgrp is a valid dispatchmgr. 00182 */ 00183 00184 00185 void 00186 dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole); 00187 /*%< 00188 * Sets the dispatcher's "blackhole list," a list of addresses that will 00189 * be ignored by all dispatchers created by the dispatchmgr. 00190 * 00191 * Requires: 00192 * \li mgrp is a valid dispatchmgr 00193 * \li blackhole is a valid acl 00194 */ 00195 00196 00197 dns_acl_t * 00198 dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr); 00199 /*%< 00200 * Gets a pointer to the dispatcher's current blackhole list, 00201 * without incrementing its reference count. 00202 * 00203 * Requires: 00204 *\li mgr is a valid dispatchmgr 00205 * Returns: 00206 *\li A pointer to the current blackhole list, or NULL. 00207 */ 00208 00209 void 00210 dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr, 00211 dns_portlist_t *portlist); 00212 /*%< 00213 * This function is deprecated. Use dns_dispatchmgr_setavailports() instead. 00214 * 00215 * Requires: 00216 *\li mgr is a valid dispatchmgr 00217 */ 00218 00219 dns_portlist_t * 00220 dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr); 00221 /*%< 00222 * This function is deprecated and always returns NULL. 00223 * 00224 * Requires: 00225 *\li mgr is a valid dispatchmgr 00226 */ 00227 00228 isc_result_t 00229 dns_dispatchmgr_setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset, 00230 isc_portset_t *v6portset); 00231 /*%< 00232 * Sets a list of UDP ports that can be used for outgoing UDP messages. 00233 * 00234 * Requires: 00235 *\li mgr is a valid dispatchmgr 00236 *\li v4portset is NULL or a valid port set 00237 *\li v6portset is NULL or a valid port set 00238 */ 00239 00240 void 00241 dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats); 00242 /*%< 00243 * Sets statistics counter for the dispatchmgr. This function is expected to 00244 * be called only on zone creation (when necessary). 00245 * Once installed, it cannot be removed or replaced. Also, there is no 00246 * interface to get the installed stats from the zone; the caller must keep the 00247 * stats to reference (e.g. dump) it later. 00248 * 00249 * Requires: 00250 *\li mgr is a valid dispatchmgr with no managed dispatch. 00251 *\li stats is a valid statistics supporting resolver statistics counters 00252 * (see dns/stats.h). 00253 */ 00254 00255 isc_result_t 00256 dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, 00257 isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, 00258 unsigned int buffersize, 00259 unsigned int maxbuffers, unsigned int maxrequests, 00260 unsigned int buckets, unsigned int increment, 00261 unsigned int attributes, unsigned int mask, 00262 dns_dispatch_t **dispp); 00263 00264 isc_result_t 00265 dns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, 00266 isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, 00267 unsigned int buffersize, 00268 unsigned int maxbuffers, unsigned int maxrequests, 00269 unsigned int buckets, unsigned int increment, 00270 unsigned int attributes, unsigned int mask, 00271 dns_dispatch_t **dispp, dns_dispatch_t *dup); 00272 /*%< 00273 * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find, 00274 * otherwise create a new UDP dispatch. 00275 * 00276 * Requires: 00277 *\li All pointer parameters be valid for their respective types. 00278 * 00279 *\li dispp != NULL && *disp == NULL 00280 * 00281 *\li 512 <= buffersize <= 64k 00282 * 00283 *\li maxbuffers > 0 00284 * 00285 *\li buckets < 2097169 00286 * 00287 *\li increment > buckets 00288 * 00289 *\li (attributes & DNS_DISPATCHATTR_TCP) == 0 00290 * 00291 * Returns: 00292 *\li ISC_R_SUCCESS -- success. 00293 * 00294 *\li Anything else -- failure. 00295 */ 00296 00297 isc_result_t 00298 dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock, 00299 isc_taskmgr_t *taskmgr, unsigned int buffersize, 00300 unsigned int maxbuffers, unsigned int maxrequests, 00301 unsigned int buckets, unsigned int increment, 00302 unsigned int attributes, dns_dispatch_t **dispp); 00303 isc_result_t 00304 dns_dispatch_createtcp2(dns_dispatchmgr_t *mgr, isc_socket_t *sock, 00305 isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, 00306 isc_sockaddr_t *destaddr, unsigned int buffersize, 00307 unsigned int maxbuffers, unsigned int maxrequests, 00308 unsigned int buckets, unsigned int increment, 00309 unsigned int attributes, dns_dispatch_t **dispp); 00310 /*%< 00311 * Create a new dns_dispatch and attach it to the provided isc_socket_t. 00312 * 00313 * For all dispatches, "buffersize" is the maximum packet size we will 00314 * accept. 00315 * 00316 * "maxbuffers" and "maxrequests" control the number of buffers in the 00317 * overall system and the number of buffers which can be allocated to 00318 * requests. 00319 * 00320 * "buckets" is the number of buckets to use, and should be prime. 00321 * 00322 * "increment" is used in a collision avoidance function, and needs to be 00323 * a prime > buckets, and not 2. 00324 * 00325 * Requires: 00326 * 00327 *\li mgr is a valid dispatch manager. 00328 * 00329 *\li sock is a valid. 00330 * 00331 *\li task is a valid task that can be used internally to this dispatcher. 00332 * 00333 * \li 512 <= buffersize <= 64k 00334 * 00335 *\li maxbuffers > 0. 00336 * 00337 *\li maxrequests <= maxbuffers. 00338 * 00339 *\li buckets < 2097169 (the next prime after 65536 * 32) 00340 * 00341 *\li increment > buckets (and prime). 00342 * 00343 *\li attributes includes #DNS_DISPATCHATTR_TCP and does not include 00344 * #DNS_DISPATCHATTR_UDP. 00345 * 00346 * Returns: 00347 *\li ISC_R_SUCCESS -- success. 00348 * 00349 *\li Anything else -- failure. 00350 */ 00351 00352 void 00353 dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp); 00354 /*%< 00355 * Attach to a dispatch handle. 00356 * 00357 * Requires: 00358 *\li disp is valid. 00359 * 00360 *\li dispp != NULL && *dispp == NULL 00361 */ 00362 00363 void 00364 dns_dispatch_detach(dns_dispatch_t **dispp); 00365 /*%< 00366 * Detaches from the dispatch. 00367 * 00368 * Requires: 00369 *\li dispp != NULL and *dispp be a valid dispatch. 00370 */ 00371 00372 void 00373 dns_dispatch_starttcp(dns_dispatch_t *disp); 00374 /*%< 00375 * Start processing of a TCP dispatch once the socket connects. 00376 * 00377 * Requires: 00378 *\li 'disp' is valid. 00379 */ 00380 00381 isc_result_t 00382 dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr, 00383 isc_sockaddr_t *localaddr, dns_dispatch_t **dispp); 00384 isc_result_t 00385 dns_dispatch_gettcp2(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr, 00386 isc_sockaddr_t *localaddr, isc_boolean_t *connected, 00387 dns_dispatch_t **dispp); 00388 /* 00389 * Attempt to connect to a existing TCP connection (connection completed 00390 * for dns_dispatch_gettcp()). 00391 */ 00392 00393 00394 isc_result_t 00395 dns_dispatch_addresponse3(dns_dispatch_t *disp, unsigned int options, 00396 isc_sockaddr_t *dest, isc_task_t *task, 00397 isc_taskaction_t action, void *arg, 00398 isc_uint16_t *idp, dns_dispentry_t **resp, 00399 isc_socketmgr_t *sockmgr); 00400 00401 isc_result_t 00402 dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest, 00403 isc_task_t *task, isc_taskaction_t action, void *arg, 00404 isc_uint16_t *idp, dns_dispentry_t **resp, 00405 isc_socketmgr_t *sockmgr); 00406 00407 isc_result_t 00408 dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest, 00409 isc_task_t *task, isc_taskaction_t action, void *arg, 00410 isc_uint16_t *idp, dns_dispentry_t **resp); 00411 /*%< 00412 * Add a response entry for this dispatch. 00413 * 00414 * "*idp" is filled in with the assigned message ID, and *resp is filled in 00415 * to contain the magic token used to request event flow stop. 00416 * 00417 * Arranges for the given task to get a callback for response packets. When 00418 * the event is delivered, it must be returned using dns_dispatch_freeevent() 00419 * or through dns_dispatch_removeresponse() for another to be delivered. 00420 * 00421 * Requires: 00422 *\li "idp" be non-NULL. 00423 * 00424 *\li "task" "action" and "arg" be set as appropriate. 00425 * 00426 *\li "dest" be non-NULL and valid. 00427 * 00428 *\li "resp" be non-NULL and *resp be NULL 00429 * 00430 *\li "sockmgr" be NULL or a valid socket manager. If 'disp' has 00431 * the DNS_DISPATCHATTR_EXCLUSIVE attribute, this must not be NULL, 00432 * which also means dns_dispatch_addresponse() cannot be used. 00433 * 00434 * Ensures: 00435 * 00436 *\li <id, dest> is a unique tuple. That means incoming messages 00437 * are identifiable. 00438 * 00439 * Returns: 00440 * 00441 *\li ISC_R_SUCCESS -- all is well. 00442 *\li ISC_R_NOMEMORY -- memory could not be allocated. 00443 *\li ISC_R_NOMORE -- no more message ids can be allocated 00444 * for this destination. 00445 */ 00446 00447 00448 void 00449 dns_dispatch_removeresponse(dns_dispentry_t **resp, 00450 dns_dispatchevent_t **sockevent); 00451 /*%< 00452 * Stops the flow of responses for the provided id and destination. 00453 * If "sockevent" is non-NULL, the dispatch event and associated buffer is 00454 * also returned to the system. 00455 * 00456 * Requires: 00457 *\li "resp" != NULL and "*resp" contain a value previously allocated 00458 * by dns_dispatch_addresponse(); 00459 * 00460 *\li May only be called from within the task given as the 'task' 00461 * argument to dns_dispatch_addresponse() when allocating '*resp'. 00462 */ 00463 00464 isc_socket_t * 00465 dns_dispatch_getentrysocket(dns_dispentry_t *resp); 00466 00467 isc_socket_t * 00468 dns_dispatch_getsocket(dns_dispatch_t *disp); 00469 /*%< 00470 * Return the socket associated with this dispatcher. 00471 * 00472 * Requires: 00473 *\li disp is valid. 00474 * 00475 * Returns: 00476 *\li The socket the dispatcher is using. 00477 */ 00478 00479 isc_result_t 00480 dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp); 00481 /*%< 00482 * Return the local address for this dispatch. 00483 * This currently only works for dispatches using UDP sockets. 00484 * 00485 * Requires: 00486 *\li disp is valid. 00487 *\li addrp to be non null. 00488 * 00489 * Returns: 00490 *\li ISC_R_SUCCESS 00491 *\li ISC_R_NOTIMPLEMENTED 00492 */ 00493 00494 void 00495 dns_dispatch_cancel(dns_dispatch_t *disp); 00496 /*%< 00497 * cancel outstanding clients 00498 * 00499 * Requires: 00500 *\li disp is valid. 00501 */ 00502 00503 unsigned int 00504 dns_dispatch_getattributes(dns_dispatch_t *disp); 00505 /*%< 00506 * Return the attributes (DNS_DISPATCHATTR_xxx) of this dispatch. Only the 00507 * non-changeable attributes are expected to be referenced by the caller. 00508 * 00509 * Requires: 00510 *\li disp is valid. 00511 */ 00512 00513 void 00514 dns_dispatch_changeattributes(dns_dispatch_t *disp, 00515 unsigned int attributes, unsigned int mask); 00516 /*%< 00517 * Set the bits described by "mask" to the corresponding values in 00518 * "attributes". 00519 * 00520 * That is: 00521 * 00522 * \code 00523 * new = (old & ~mask) | (attributes & mask) 00524 * \endcode 00525 * 00526 * This function has a side effect when #DNS_DISPATCHATTR_NOLISTEN changes. 00527 * When the flag becomes off, the dispatch will start receiving on the 00528 * corresponding socket. When the flag becomes on, receive events on the 00529 * corresponding socket will be canceled. 00530 * 00531 * Requires: 00532 *\li disp is valid. 00533 * 00534 *\li attributes are reasonable for the dispatch. That is, setting the UDP 00535 * attribute on a TCP socket isn't reasonable. 00536 */ 00537 00538 void 00539 dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event); 00540 /*%< 00541 * Inform the dispatcher of a socket receive. This is used for sockets 00542 * shared between dispatchers and clients. If the dispatcher fails to copy 00543 * or send the event, nothing happens. 00544 * 00545 * Requires: 00546 *\li disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set. 00547 * event != NULL 00548 */ 00549 00550 dns_dispatch_t * 00551 dns_dispatchset_get(dns_dispatchset_t *dset); 00552 /*%< 00553 * Retrieve the next dispatch from dispatch set 'dset', and increment 00554 * the round-robin counter. 00555 * 00556 * Requires: 00557 *\li dset != NULL 00558 */ 00559 00560 isc_result_t 00561 dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr, 00562 isc_taskmgr_t *taskmgr, dns_dispatch_t *source, 00563 dns_dispatchset_t **dsetp, int n); 00564 /*%< 00565 * Given a valid dispatch 'source', create a dispatch set containing 00566 * 'n' UDP dispatches, with the remainder filled out by clones of the 00567 * source. 00568 * 00569 * Requires: 00570 *\li source is a valid UDP dispatcher 00571 *\li dsetp != NULL, *dsetp == NULL 00572 */ 00573 00574 void 00575 dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task); 00576 /*%< 00577 * Cancel socket operations for the dispatches in 'dset'. 00578 */ 00579 00580 void 00581 dns_dispatchset_destroy(dns_dispatchset_t **dsetp); 00582 /*%< 00583 * Dereference all the dispatches in '*dsetp', free the dispatchset 00584 * memory, and set *dsetp to NULL. 00585 * 00586 * Requires: 00587 *\li dset is valid 00588 */ 00589 00590 void 00591 dns_dispatch_setdscp(dns_dispatch_t *disp, isc_dscp_t dscp); 00592 isc_dscp_t 00593 dns_dispatch_getdscp(dns_dispatch_t *disp); 00594 /*%< 00595 * Set/get the DSCP value to be used when sending responses to clients, 00596 * as defined in the "listen-on" or "listen-on-v6" statements. 00597 * 00598 * Requires: 00599 *\li disp is valid. 00600 */ 00601 00602 ISC_LANG_ENDDECLS 00603 00604 #endif /* DNS_DISPATCH_H */