"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.17.5/lib/dns/include/dns/dispatch.h" (4 Sep 2020, 15539 Bytes) of package /linux/misc/dns/bind9/9.17.5/bind-9.17.5.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "dispatch.h" see the Fossies "Dox" file reference documentation.

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