dispatch.h

Go to the documentation of this file.
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   &lt;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 */

Generated on Tue Apr 28 17:40:57 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha