"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.16.7/lib/ns/include/ns/client.h" (4 Sep 2020, 16223 Bytes) of package /linux/misc/dns/bind9/9.16.7/bind-9.16.7.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 "client.h" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.17.3_vs_9.17.4.

    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 NS_CLIENT_H
   13 #define NS_CLIENT_H 1
   14 
   15 /*****
   16 ***** Module Info
   17 *****/
   18 
   19 /*! \file
   20  * \brief
   21  * This module defines two objects, ns_client_t and ns_clientmgr_t.
   22  *
   23  * An ns_client_t object handles incoming DNS requests from clients
   24  * on a given network interface.
   25  *
   26  * Each ns_client_t object can handle only one TCP connection or UDP
   27  * request at a time.  Therefore, several ns_client_t objects are
   28  * typically created to serve each network interface, e.g., one
   29  * for handling TCP requests and a few (one per CPU) for handling
   30  * UDP requests.
   31  *
   32  * Incoming requests are classified as queries, zone transfer
   33  * requests, update requests, notify requests, etc, and handed off
   34  * to the appropriate request handler.  When the request has been
   35  * fully handled (which can be much later), the ns_client_t must be
   36  * notified of this by calling one of the following functions
   37  * exactly once in the context of its task:
   38  * \code
   39  *   ns_client_send()    (sending a non-error response)
   40  *   ns_client_sendraw() (sending a raw response)
   41  *   ns_client_error()   (sending an error response)
   42  *   ns_client_drop() (sending no response, logging the reason)
   43  *\endcode
   44  * This will release any resources used by the request and
   45  * and allow the ns_client_t to listen for the next request.
   46  *
   47  * A ns_clientmgr_t manages a number of ns_client_t objects.
   48  * New ns_client_t objects are created by calling
   49  * ns_clientmgr_createclients(). They are destroyed by
   50  * destroying their manager.
   51  */
   52 
   53 /***
   54  *** Imports
   55  ***/
   56 
   57 #include <inttypes.h>
   58 #include <stdbool.h>
   59 
   60 #include <isc/atomic.h>
   61 #include <isc/buffer.h>
   62 #include <isc/magic.h>
   63 #include <isc/netmgr.h>
   64 #include <isc/platform.h>
   65 #include <isc/quota.h>
   66 #include <isc/stdtime.h>
   67 
   68 #include <dns/db.h>
   69 #include <dns/ecs.h>
   70 #include <dns/fixedname.h>
   71 #include <dns/name.h>
   72 #include <dns/rdataclass.h>
   73 #include <dns/rdatatype.h>
   74 #include <dns/tcpmsg.h>
   75 #include <dns/types.h>
   76 
   77 #include <ns/query.h>
   78 #include <ns/types.h>
   79 
   80 /***
   81  *** Types
   82  ***/
   83 
   84 #define NS_CLIENT_TCP_BUFFER_SIZE  65535
   85 #define NS_CLIENT_SEND_BUFFER_SIZE 4096
   86 
   87 /*!
   88  * Client object states.  Ordering is significant: higher-numbered
   89  * states are generally "more active", meaning that the client can
   90  * have more dynamically allocated data, outstanding events, etc.
   91  * In the list below, any such properties listed for state N
   92  * also apply to any state > N.
   93  */
   94 
   95 typedef enum {
   96     NS_CLIENTSTATE_FREED = 0,
   97     /*%<
   98      * The client object no longer exists.
   99      */
  100 
  101     NS_CLIENTSTATE_INACTIVE = 1,
  102     /*%<
  103      * The client object exists and has a task and timer.
  104      * Its "query" struct and sendbuf are initialized.
  105      * It has a message and OPT, both in the reset state.
  106      */
  107 
  108     NS_CLIENTSTATE_READY = 2,
  109     /*%<
  110      * The client object is either a TCP or a UDP one, and
  111      * it is associated with a network interface.  It is on the
  112      * client manager's list of active clients.
  113      *
  114      * If it is a TCP client object, it has a TCP listener socket
  115      * and an outstanding TCP listen request.
  116      *
  117      * If it is a UDP client object, it has a UDP listener socket
  118      * and an outstanding UDP receive request.
  119      */
  120 
  121     NS_CLIENTSTATE_WORKING = 3,
  122     /*%<
  123      * The client object has received a request and is working
  124      * on it.  It has a view, and it may have any of a non-reset OPT,
  125      * recursion quota, and an outstanding write request.
  126      */
  127 
  128     NS_CLIENTSTATE_RECURSING = 4,
  129     /*%<
  130      * The client object is recursing.  It will be on the
  131      * 'recursing' list.
  132      */
  133 
  134     NS_CLIENTSTATE_MAX = 5
  135     /*%<
  136      * Sentinel value used to indicate "no state".
  137      */
  138 } ns_clientstate_t;
  139 
  140 typedef ISC_LIST(ns_client_t) client_list_t;
  141 
  142 /*% nameserver client manager structure */
  143 struct ns_clientmgr {
  144     /* Unlocked. */
  145     unsigned int magic;
  146 
  147     isc_mem_t * mctx;
  148     ns_server_t *   sctx;
  149     isc_taskmgr_t * taskmgr;
  150     isc_timermgr_t *timermgr;
  151     isc_task_t *    excl;
  152     isc_refcount_t  references;
  153     int     ncpus;
  154 
  155     /* Attached by clients, needed for e.g. recursion */
  156     isc_task_t **taskpool;
  157 
  158     ns_interface_t *interface;
  159 
  160     /* Lock covers manager state. */
  161     isc_mutex_t lock;
  162     bool        exiting;
  163 
  164     /* Lock covers the recursing list */
  165     isc_mutex_t   reclock;
  166     client_list_t recursing; /*%< Recursing clients */
  167 
  168     /*%< mctx pool for clients. */
  169     isc_mem_t **mctxpool;
  170 };
  171 
  172 /*% nameserver client structure */
  173 struct ns_client {
  174     unsigned int     magic;
  175     isc_mem_t *  mctx;
  176     bool         allocated; /* Do we need to free it? */
  177     ns_server_t *    sctx;
  178     ns_clientmgr_t * manager;
  179     ns_clientstate_t state;
  180     int      nupdates;
  181     bool         shuttingdown;
  182     unsigned int     attributes;
  183     isc_task_t *     task;
  184     dns_view_t *     view;
  185     dns_dispatch_t * dispatch;
  186     isc_nmhandle_t * handle;
  187     unsigned char *  tcpbuf;
  188     dns_message_t *  message;
  189     unsigned char *  sendbuf;
  190     dns_rdataset_t * opt;
  191     uint16_t     udpsize;
  192     uint16_t     extflags;
  193     int16_t      ednsversion; /* -1 noedns */
  194     void (*cleanup)(ns_client_t *);
  195     void (*shutdown)(void *arg, isc_result_t result);
  196     void *        shutdown_arg;
  197     ns_query_t    query;
  198     isc_time_t    requesttime;
  199     isc_stdtime_t now;
  200     isc_time_t    tnow;
  201     dns_name_t    signername; /*%< [T]SIG key name */
  202     dns_name_t *  signer;     /*%< NULL if not valid sig */
  203     bool          mortal;     /*%< Die after handling request */
  204     isc_quota_t * recursionquota;
  205 
  206     isc_sockaddr_t peeraddr;
  207     bool           peeraddr_valid;
  208     isc_netaddr_t  destaddr;
  209     isc_sockaddr_t destsockaddr;
  210 
  211     dns_ecs_t ecs; /*%< EDNS client subnet sent by client */
  212 
  213     struct in6_pktinfo pktinfo;
  214     isc_dscp_t     dscp;
  215     /*%
  216      * Information about recent FORMERR response(s), for
  217      * FORMERR loop avoidance.  This is separate for each
  218      * client object rather than global only to avoid
  219      * the need for locking.
  220      */
  221     struct {
  222         isc_sockaddr_t  addr;
  223         isc_stdtime_t   time;
  224         dns_messageid_t id;
  225     } formerrcache;
  226 
  227     /*% Callback function to send a response when unit testing */
  228     void (*sendcb)(isc_buffer_t *buf);
  229 
  230     ISC_LINK(ns_client_t) rlink;
  231     unsigned char  cookie[8];
  232     uint32_t       expire;
  233     unsigned char *keytag;
  234     uint16_t       keytag_len;
  235 
  236     /*%
  237      * Used to override the DNS response code in ns_client_error().
  238      * If set to -1, the rcode is determined from the result code,
  239      * but if set to any other value, the least significant 12
  240      * bits will be used as the rcode in the response message.
  241      */
  242     int32_t rcode_override;
  243 };
  244 
  245 #define NS_CLIENT_MAGIC    ISC_MAGIC('N', 'S', 'C', 'c')
  246 #define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
  247 
  248 #define NS_CLIENTATTR_TCP    0x00001
  249 #define NS_CLIENTATTR_RA     0x00002 /*%< Client gets recursive service */
  250 #define NS_CLIENTATTR_PKTINFO    0x00004 /*%< pktinfo is valid */
  251 #define NS_CLIENTATTR_MULTICAST  0x00008 /*%< recv'd from multicast */
  252 #define NS_CLIENTATTR_WANTDNSSEC 0x00010 /*%< include dnssec records */
  253 #define NS_CLIENTATTR_WANTNSID   0x00020 /*%< include nameserver ID */
  254 /* Obsolete: NS_CLIENTATTR_FILTER_AAAA  0x00040 */
  255 /* Obsolete: NS_CLIENTATTR_FILTER_AAAA_RC 0x00080 */
  256 #define NS_CLIENTATTR_WANTAD       0x00100 /*%< want AD in response if possible */
  257 #define NS_CLIENTATTR_WANTCOOKIE   0x00200 /*%< return a COOKIE */
  258 #define NS_CLIENTATTR_HAVECOOKIE   0x00400 /*%< has a valid COOKIE */
  259 #define NS_CLIENTATTR_WANTEXPIRE   0x00800 /*%< return seconds to expire */
  260 #define NS_CLIENTATTR_HAVEEXPIRE   0x01000 /*%< return seconds to expire */
  261 #define NS_CLIENTATTR_WANTOPT      0x02000 /*%< add opt to reply */
  262 #define NS_CLIENTATTR_HAVEECS      0x04000 /*%< received an ECS option */
  263 #define NS_CLIENTATTR_WANTPAD      0x08000 /*%< pad reply */
  264 #define NS_CLIENTATTR_USEKEEPALIVE 0x10000 /*%< use TCP keepalive */
  265 
  266 #define NS_CLIENTATTR_NOSETFC   0x20000 /*%< don't set servfail cache */
  267 #define NS_CLIENTATTR_RECURSING 0x40000 /*%< client is recursing */
  268 
  269 /*
  270  * Flag to use with the SERVFAIL cache to indicate
  271  * that a query had the CD bit set.
  272  */
  273 #define NS_FAILCACHE_CD 0x01
  274 
  275 #if defined(_WIN32) && !defined(_WIN64)
  276 LIBNS_EXTERNAL_DATA extern atomic_uint_fast32_t ns_client_requests;
  277 #else  /* if defined(_WIN32) && !defined(_WIN64) */
  278 LIBNS_EXTERNAL_DATA extern atomic_uint_fast64_t ns_client_requests;
  279 #endif /* if defined(_WIN32) && !defined(_WIN64) */
  280 
  281 /***
  282  *** Functions
  283  ***/
  284 
  285 /*
  286  * Note!  These ns_client_ routines MUST be called ONLY from the client's
  287  * task in order to ensure synchronization.
  288  */
  289 
  290 void
  291 ns_client_send(ns_client_t *client);
  292 /*%<
  293  * Finish processing the current client request and
  294  * send client->message as a response.
  295  * \brief
  296  * Note!  These ns_client_ routines MUST be called ONLY from the client's
  297  * task in order to ensure synchronization.
  298  */
  299 
  300 void
  301 ns_client_sendraw(ns_client_t *client, dns_message_t *msg);
  302 /*%<
  303  * Finish processing the current client request and
  304  * send msg as a response using client->message->id for the id.
  305  */
  306 
  307 void
  308 ns_client_error(ns_client_t *client, isc_result_t result);
  309 /*%<
  310  * Finish processing the current client request and return
  311  * an error response to the client.  The error response
  312  * will have an RCODE determined by 'result'.
  313  */
  314 
  315 void
  316 ns_client_drop(ns_client_t *client, isc_result_t result);
  317 /*%<
  318  * Log the reason the current client request has failed; no response
  319  * will be sent.
  320  */
  321 
  322 bool
  323 ns_client_shuttingdown(ns_client_t *client);
  324 /*%<
  325  * Return true iff the client is currently shutting down.
  326  */
  327 
  328 isc_result_t
  329 ns_client_replace(ns_client_t *client);
  330 /*%<
  331  * Try to replace the current client with a new one, so that the
  332  * current one can go off and do some lengthy work without
  333  * leaving the dispatch/socket without service.
  334  */
  335 
  336 void
  337 ns_client_settimeout(ns_client_t *client, unsigned int seconds);
  338 /*%<
  339  * Set a timer in the client to go off in the specified amount of time.
  340  */
  341 
  342 isc_result_t
  343 ns_clientmgr_create(isc_mem_t *mctx, ns_server_t *sctx, isc_taskmgr_t *taskmgr,
  344             isc_timermgr_t *timermgr, ns_interface_t *ifp, int ncpus,
  345             ns_clientmgr_t **managerp);
  346 /*%<
  347  * Create a client manager.
  348  */
  349 
  350 void
  351 ns_clientmgr_destroy(ns_clientmgr_t **managerp);
  352 /*%<
  353  * Destroy a client manager and all ns_client_t objects
  354  * managed by it.
  355  */
  356 
  357 isc_sockaddr_t *
  358 ns_client_getsockaddr(ns_client_t *client);
  359 /*%<
  360  * Get the socket address of the client whose request is
  361  * currently being processed.
  362  */
  363 
  364 isc_sockaddr_t *
  365 ns_client_getdestaddr(ns_client_t *client);
  366 /*%<
  367  * Get the destination address (server) for the request that is
  368  * currently being processed.
  369  */
  370 
  371 isc_result_t
  372 ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
  373              dns_acl_t *acl, bool default_allow);
  374 
  375 /*%<
  376  * Convenience function for client request ACL checking.
  377  *
  378  * Check the current client request against 'acl'.  If 'acl'
  379  * is NULL, allow the request iff 'default_allow' is true.
  380  * If netaddr is NULL, check the ACL against client->peeraddr;
  381  * otherwise check it against netaddr.
  382  *
  383  * Notes:
  384  *\li   This is appropriate for checking allow-update,
  385  *  allow-query, allow-transfer, etc.  It is not appropriate
  386  *  for checking the blackhole list because we treat positive
  387  *  matches as "allow" and negative matches as "deny"; in
  388  *  the case of the blackhole list this would be backwards.
  389  *
  390  * Requires:
  391  *\li   'client' points to a valid client.
  392  *\li   'netaddr' points to a valid address, or is NULL.
  393  *\li   'acl' points to a valid ACL, or is NULL.
  394  *
  395  * Returns:
  396  *\li   ISC_R_SUCCESS   if the request should be allowed
  397  * \li  DNS_R_REFUSED   if the request should be denied
  398  *\li   No other return values are possible.
  399  */
  400 
  401 isc_result_t
  402 ns_client_checkacl(ns_client_t *client, isc_sockaddr_t *sockaddr,
  403            const char *opname, dns_acl_t *acl, bool default_allow,
  404            int log_level);
  405 /*%<
  406  * Like ns_client_checkaclsilent, except the outcome of the check is
  407  * logged at log level 'log_level' if denied, and at debug 3 if approved.
  408  * Log messages will refer to the request as an 'opname' request.
  409  *
  410  * Requires:
  411  *\li   'client' points to a valid client.
  412  *\li   'sockaddr' points to a valid address, or is NULL.
  413  *\li   'acl' points to a valid ACL, or is NULL.
  414  *\li   'opname' points to a null-terminated string.
  415  */
  416 
  417 void
  418 ns_client_log(ns_client_t *client, isc_logcategory_t *category,
  419           isc_logmodule_t *module, int level, const char *fmt, ...)
  420     ISC_FORMAT_PRINTF(5, 6);
  421 
  422 void
  423 ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
  424            isc_logmodule_t *module, int level, const char *fmt, va_list ap)
  425     ISC_FORMAT_PRINTF(5, 0);
  426 
  427 void
  428 ns_client_aclmsg(const char *msg, const dns_name_t *name, dns_rdatatype_t type,
  429          dns_rdataclass_t rdclass, char *buf, size_t len);
  430 
  431 #define NS_CLIENT_ACLMSGSIZE(x)                           \
  432     (DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \
  433      DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'"))
  434 
  435 void
  436 ns_client_recursing(ns_client_t *client);
  437 /*%<
  438  * Add client to end of th recursing list.
  439  */
  440 
  441 void
  442 ns_client_killoldestquery(ns_client_t *client);
  443 /*%<
  444  * Kill the oldest recursive query (recursing list head).
  445  */
  446 
  447 void
  448 ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager);
  449 /*%<
  450  * Dump the outstanding recursive queries to 'f'.
  451  */
  452 
  453 void
  454 ns_client_qnamereplace(ns_client_t *client, dns_name_t *name);
  455 /*%<
  456  * Replace the qname.
  457  */
  458 
  459 isc_result_t
  460 ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp);
  461 
  462 isc_result_t
  463 ns_client_addopt(ns_client_t *client, dns_message_t *message,
  464          dns_rdataset_t **opt);
  465 
  466 /*%<
  467  * Get a client object from the inactive queue, or create one, as needed.
  468  * (Not intended for use outside this module and associated tests.)
  469  */
  470 
  471 void
  472 ns__client_request(isc_nmhandle_t *handle, isc_region_t *region, void *arg);
  473 
  474 /*%<
  475  * Handle client requests.
  476  * (Not intended for use outside this module and associated tests.)
  477  */
  478 
  479 isc_result_t
  480 ns__client_tcpconn(isc_nmhandle_t *handle, isc_result_t result, void *arg);
  481 
  482 /*%<
  483  * Called every time a TCP connection is establish.  This is used for
  484  * updating TCP statistics.
  485  */
  486 
  487 dns_rdataset_t *
  488 ns_client_newrdataset(ns_client_t *client);
  489 
  490 void
  491 ns_client_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp);
  492 /*%<
  493  * Get and release temporary rdatasets in the client message;
  494  * used in query.c and in plugins.
  495  */
  496 
  497 isc_result_t
  498 ns_client_newnamebuf(ns_client_t *client);
  499 /*%<
  500  * Allocate a name buffer for the client message.
  501  */
  502 
  503 dns_name_t *
  504 ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf);
  505 /*%<
  506  * Get a temporary name for the client message.
  507  */
  508 
  509 isc_buffer_t *
  510 ns_client_getnamebuf(ns_client_t *client);
  511 /*%<
  512  * Get a name buffer from the pool, or allocate a new one if needed.
  513  */
  514 
  515 void
  516 ns_client_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf);
  517 /*%<
  518  * Adjust buffer 'dbuf' to reflect that 'name' is using space in it,
  519  * and set client attributes appropriately.
  520  */
  521 
  522 void
  523 ns_client_releasename(ns_client_t *client, dns_name_t **namep);
  524 /*%<
  525  * Release 'name' back to the pool of temporary names for the client
  526  * message. If it is using a name buffer, relinquish its exclusive
  527  * rights on the buffer.
  528  */
  529 
  530 isc_result_t
  531 ns_client_newdbversion(ns_client_t *client, unsigned int n);
  532 /*%<
  533  * Allocate 'n' new database versions for use by client queries.
  534  */
  535 
  536 ns_dbversion_t *
  537 ns_client_getdbversion(ns_client_t *client);
  538 /*%<
  539  * Get a free database version for use by a client query, allocating
  540  * a new one if necessary.
  541  */
  542 
  543 ns_dbversion_t *
  544 ns_client_findversion(ns_client_t *client, dns_db_t *db);
  545 /*%<
  546  * Find the correct database version to use with a client query.
  547  * If we have already done a query related to the database 'db',
  548  * make sure subsequent queries are from the same version;
  549  * otherwise, take a database version from the list of dbversions
  550  * allocated by ns_client_newdbversion().
  551  */
  552 
  553 isc_result_t
  554 ns__client_setup(ns_client_t *client, ns_clientmgr_t *manager, bool new);
  555 /*%<
  556  * Perform initial setup of an allocated client.
  557  */
  558 
  559 void
  560 ns__client_reset_cb(void *client0);
  561 /*%<
  562  * Reset the client object so that it can be reused.
  563  */
  564 
  565 void
  566 ns__client_put_cb(void *client0);
  567 /*%<
  568  * Free all resources allocated to this client object, so that
  569  * it can be freed.
  570  */
  571 
  572 #endif /* NS_CLIENT_H */