client.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 /* $Id: client.h,v 1.96 2012/01/31 23:47:31 tbox Exp $ */
00019 
00020 #ifndef NAMED_CLIENT_H
00021 #define NAMED_CLIENT_H 1
00022 
00023 /*****
00024  ***** Module Info
00025  *****/
00026 
00027 /*! \file
00028  * \brief
00029  * This module defines two objects, ns_client_t and ns_clientmgr_t.
00030  *
00031  * An ns_client_t object handles incoming DNS requests from clients
00032  * on a given network interface.
00033  *
00034  * Each ns_client_t object can handle only one TCP connection or UDP
00035  * request at a time.  Therefore, several ns_client_t objects are
00036  * typically created to serve each network interface, e.g., one
00037  * for handling TCP requests and a few (one per CPU) for handling
00038  * UDP requests.
00039  *
00040  * Incoming requests are classified as queries, zone transfer
00041  * requests, update requests, notify requests, etc, and handed off
00042  * to the appropriate request handler.  When the request has been
00043  * fully handled (which can be much later), the ns_client_t must be
00044  * notified of this by calling one of the following functions
00045  * exactly once in the context of its task:
00046  * \code
00047  *   ns_client_send()   (sending a non-error response)
00048  *   ns_client_sendraw() (sending a raw response)
00049  *   ns_client_error()  (sending an error response)
00050  *   ns_client_next()   (sending no response)
00051  *\endcode
00052  * This will release any resources used by the request and
00053  * and allow the ns_client_t to listen for the next request.
00054  *
00055  * A ns_clientmgr_t manages a number of ns_client_t objects.
00056  * New ns_client_t objects are created by calling
00057  * ns_clientmgr_createclients(). They are destroyed by
00058  * destroying their manager.
00059  */
00060 
00061 /***
00062  *** Imports
00063  ***/
00064 
00065 #include <isc/buffer.h>
00066 #include <isc/magic.h>
00067 #include <isc/stdtime.h>
00068 #include <isc/quota.h>
00069 #include <isc/queue.h>
00070 
00071 #include <dns/db.h>
00072 #include <dns/fixedname.h>
00073 #include <dns/name.h>
00074 #include <dns/rdataclass.h>
00075 #include <dns/rdatatype.h>
00076 #include <dns/tcpmsg.h>
00077 #include <dns/types.h>
00078 
00079 #include <named/types.h>
00080 #include <named/query.h>
00081 
00082 /***
00083  *** Types
00084  ***/
00085 
00086 /*% nameserver client structure */
00087 struct ns_client {
00088         unsigned int            magic;
00089         isc_mem_t *             mctx;
00090         ns_clientmgr_t *        manager;
00091         int                     state;
00092         int                     newstate;
00093         int                     naccepts;
00094         int                     nreads;
00095         int                     nsends;
00096         int                     nrecvs;
00097         int                     nupdates;
00098         int                     nctls;
00099         int                     references;
00100         isc_boolean_t           needshutdown;   /*
00101                                                  * Used by clienttest to get
00102                                                  * the client to go from
00103                                                  * inactive to free state
00104                                                  * by shutting down the
00105                                                  * client's task.
00106                                                  */
00107         unsigned int            attributes;
00108         isc_task_t *            task;
00109         dns_view_t *            view;
00110         dns_dispatch_t *        dispatch;
00111         isc_socket_t *          udpsocket;
00112         isc_socket_t *          tcplistener;
00113         isc_socket_t *          tcpsocket;
00114         unsigned char *         tcpbuf;
00115         dns_tcpmsg_t            tcpmsg;
00116         isc_boolean_t           tcpmsg_valid;
00117         isc_timer_t *           timer;
00118         isc_timer_t *           delaytimer;
00119         isc_boolean_t           timerset;
00120         dns_message_t *         message;
00121         isc_socketevent_t *     sendevent;
00122         isc_socketevent_t *     recvevent;
00123         unsigned char *         recvbuf;
00124         dns_rdataset_t *        opt;
00125         isc_uint16_t            udpsize;
00126         isc_uint16_t            extflags;
00127         isc_int16_t             ednsversion;    /* -1 noedns */
00128         void                    (*next)(ns_client_t *);
00129         void                    (*shutdown)(void *arg, isc_result_t result);
00130         void                    *shutdown_arg;
00131         ns_query_t              query;
00132         isc_stdtime_t           requesttime;
00133         isc_stdtime_t           now;
00134         isc_time_t              tnow;
00135         dns_name_t              signername;   /*%< [T]SIG key name */
00136         dns_name_t *            signer;       /*%< NULL if not valid sig */
00137         isc_boolean_t           mortal;       /*%< Die after handling request */
00138         isc_boolean_t           pipelined;   /*%< TCP queries not in sequence */
00139         isc_quota_t             *tcpquota;
00140         isc_quota_t             *recursionquota;
00141         ns_interface_t          *interface;
00142 
00143         isc_sockaddr_t          peeraddr;
00144         isc_boolean_t           peeraddr_valid;
00145         isc_netaddr_t           destaddr;
00146 
00147         isc_netaddr_t           ecs_addr;       /*%< EDNS client subnet */
00148         isc_uint8_t             ecs_addrlen;
00149         isc_uint8_t             ecs_scope;
00150 
00151         struct in6_pktinfo      pktinfo;
00152         isc_dscp_t              dscp;
00153         isc_event_t             ctlevent;
00154 #ifdef ALLOW_FILTER_AAAA
00155         dns_aaaa_t              filter_aaaa;
00156 #endif
00157         /*%
00158          * Information about recent FORMERR response(s), for
00159          * FORMERR loop avoidance.  This is separate for each
00160          * client object rather than global only to avoid
00161          * the need for locking.
00162          */
00163         struct {
00164                 isc_sockaddr_t          addr;
00165                 isc_stdtime_t           time;
00166                 dns_messageid_t         id;
00167         } formerrcache;
00168 
00169         ISC_LINK(ns_client_t)   link;
00170         ISC_LINK(ns_client_t)   rlink;
00171         ISC_QLINK(ns_client_t)  ilink;
00172         unsigned char           cookie[8];
00173         isc_uint32_t            expire;
00174 };
00175 
00176 typedef ISC_QUEUE(ns_client_t) client_queue_t;
00177 typedef ISC_LIST(ns_client_t) client_list_t;
00178 
00179 #define NS_CLIENT_MAGIC                 ISC_MAGIC('N','S','C','c')
00180 #define NS_CLIENT_VALID(c)              ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
00181 
00182 #define NS_CLIENTATTR_TCP               0x0001
00183 #define NS_CLIENTATTR_RA                0x0002 /*%< Client gets recursive service */
00184 #define NS_CLIENTATTR_PKTINFO           0x0004 /*%< pktinfo is valid */
00185 #define NS_CLIENTATTR_MULTICAST         0x0008 /*%< recv'd from multicast */
00186 #define NS_CLIENTATTR_WANTDNSSEC        0x0010 /*%< include dnssec records */
00187 #define NS_CLIENTATTR_WANTNSID          0x0020 /*%< include nameserver ID */
00188 #ifdef ALLOW_FILTER_AAAA
00189 #define NS_CLIENTATTR_FILTER_AAAA       0x0040 /*%< suppress AAAAs */
00190 #define NS_CLIENTATTR_FILTER_AAAA_RC    0x0080 /*%< recursing for A against AAAA */
00191 #endif
00192 #define NS_CLIENTATTR_WANTAD            0x0100 /*%< want AD in response if possible */
00193 #define NS_CLIENTATTR_WANTSIT           0x0200 /*%< include SIT */
00194 #define NS_CLIENTATTR_HAVESIT           0x0400 /*%< has a valid SIT */
00195 #define NS_CLIENTATTR_WANTEXPIRE        0x0800 /*%< return seconds to expire */
00196 #define NS_CLIENTATTR_HAVEEXPIRE        0x1000 /*%< return seconds to expire */
00197 #define NS_CLIENTATTR_WANTOPT           0x2000 /*%< add opt to reply */
00198 #define NS_CLIENTATTR_HAVEECS           0x4000 /*%< sent an ECS option */
00199 
00200 #define NS_CLIENTATTR_NOSETFC           0x8000 /*%< don't set servfail cache */
00201 
00202 /*
00203  * Flag to use with the SERVFAIL cache to indicate
00204  * that a query had the CD bit set.
00205  */
00206 #define NS_FAILCACHE_CD         0x01
00207 
00208 
00209 
00210 extern unsigned int ns_client_requests;
00211 
00212 /***
00213  *** Functions
00214  ***/
00215 
00216 /*%
00217  * Note!  These ns_client_ routines MUST be called ONLY from the client's
00218  * task in order to ensure synchronization.
00219  */
00220 
00221 void
00222 ns_client_send(ns_client_t *client);
00223 /*%
00224  * Finish processing the current client request and
00225  * send client->message as a response.
00226  * \brief
00227  * Note!  These ns_client_ routines MUST be called ONLY from the client's
00228  * task in order to ensure synchronization.
00229  */
00230 
00231 void
00232 ns_client_sendraw(ns_client_t *client, dns_message_t *msg);
00233 /*%
00234  * Finish processing the current client request and
00235  * send msg as a response using client->message->id for the id.
00236  */
00237 
00238 void
00239 ns_client_error(ns_client_t *client, isc_result_t result);
00240 /*%
00241  * Finish processing the current client request and return
00242  * an error response to the client.  The error response
00243  * will have an RCODE determined by 'result'.
00244  */
00245 
00246 void
00247 ns_client_next(ns_client_t *client, isc_result_t result);
00248 /*%
00249  * Finish processing the current client request,
00250  * return no response to the client.
00251  */
00252 
00253 isc_boolean_t
00254 ns_client_shuttingdown(ns_client_t *client);
00255 /*%
00256  * Return ISC_TRUE iff the client is currently shutting down.
00257  */
00258 
00259 void
00260 ns_client_attach(ns_client_t *source, ns_client_t **target);
00261 /*%
00262  * Attach '*targetp' to 'source'.
00263  */
00264 
00265 void
00266 ns_client_detach(ns_client_t **clientp);
00267 /*%
00268  * Detach '*clientp' from its client.
00269  */
00270 
00271 isc_result_t
00272 ns_client_replace(ns_client_t *client);
00273 /*%
00274  * Try to replace the current client with a new one, so that the
00275  * current one can go off and do some lengthy work without
00276  * leaving the dispatch/socket without service.
00277  */
00278 
00279 void
00280 ns_client_settimeout(ns_client_t *client, unsigned int seconds);
00281 /*%
00282  * Set a timer in the client to go off in the specified amount of time.
00283  */
00284 
00285 isc_result_t
00286 ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
00287                     isc_timermgr_t *timermgr, ns_clientmgr_t **managerp);
00288 /*%
00289  * Create a client manager.
00290  */
00291 
00292 void
00293 ns_clientmgr_destroy(ns_clientmgr_t **managerp);
00294 /*%
00295  * Destroy a client manager and all ns_client_t objects
00296  * managed by it.
00297  */
00298 
00299 isc_result_t
00300 ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
00301                            ns_interface_t *ifp, isc_boolean_t tcp);
00302 /*%
00303  * Create up to 'n' clients listening on interface 'ifp'.
00304  * If 'tcp' is ISC_TRUE, the clients will listen for TCP connections,
00305  * otherwise for UDP requests.
00306  */
00307 
00308 isc_sockaddr_t *
00309 ns_client_getsockaddr(ns_client_t *client);
00310 /*%
00311  * Get the socket address of the client whose request is
00312  * currently being processed.
00313  */
00314 
00315 isc_result_t
00316 ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
00317                          dns_acl_t *acl, isc_boolean_t default_allow);
00318 
00319 /*%
00320  * Convenience function for client request ACL checking.
00321  *
00322  * Check the current client request against 'acl'.  If 'acl'
00323  * is NULL, allow the request iff 'default_allow' is ISC_TRUE.
00324  * If netaddr is NULL, check the ACL against client->peeraddr;
00325  * otherwise check it against netaddr.
00326  *
00327  * Notes:
00328  *\li   This is appropriate for checking allow-update,
00329  *      allow-query, allow-transfer, etc.  It is not appropriate
00330  *      for checking the blackhole list because we treat positive
00331  *      matches as "allow" and negative matches as "deny"; in
00332  *      the case of the blackhole list this would be backwards.
00333  *
00334  * Requires:
00335  *\li   'client' points to a valid client.
00336  *\li   'netaddr' points to a valid address, or is NULL.
00337  *\li   'acl' points to a valid ACL, or is NULL.
00338  *
00339  * Returns:
00340  *\li   ISC_R_SUCCESS   if the request should be allowed
00341  * \li  DNS_R_REFUSED   if the request should be denied
00342  *\li   No other return values are possible.
00343  */
00344 
00345 isc_result_t
00346 ns_client_checkacl(ns_client_t  *client,
00347                    isc_sockaddr_t *sockaddr,
00348                    const char *opname, dns_acl_t *acl,
00349                    isc_boolean_t default_allow,
00350                    int log_level);
00351 /*%
00352  * Like ns_client_checkaclsilent, except the outcome of the check is
00353  * logged at log level 'log_level' if denied, and at debug 3 if approved.
00354  * Log messages will refer to the request as an 'opname' request.
00355  *
00356  * Requires:
00357  *\li   'client' points to a valid client.
00358  *\li   'sockaddr' points to a valid address, or is NULL.
00359  *\li   'acl' points to a valid ACL, or is NULL.
00360  *\li   'opname' points to a null-terminated string.
00361  */
00362 
00363 void
00364 ns_client_log(ns_client_t *client, isc_logcategory_t *category,
00365               isc_logmodule_t *module, int level,
00366               const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6);
00367 
00368 void
00369 ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
00370                isc_logmodule_t *module, int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0);
00371 
00372 void
00373 ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type,
00374                  dns_rdataclass_t rdclass, char *buf, size_t len);
00375 
00376 #define NS_CLIENT_ACLMSGSIZE(x) \
00377         (DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \
00378          DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'"))
00379 
00380 void
00381 ns_client_recursing(ns_client_t *client);
00382 /*%
00383  * Add client to end of th recursing list.
00384  */
00385 
00386 void
00387 ns_client_killoldestquery(ns_client_t *client);
00388 /*%
00389  * Kill the oldest recursive query (recursing list head).
00390  */
00391 
00392 void
00393 ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager);
00394 /*%
00395  * Dump the outstanding recursive queries to 'f'.
00396  */
00397 
00398 void
00399 ns_client_qnamereplace(ns_client_t *client, dns_name_t *name);
00400 /*%
00401  * Replace the qname.
00402  */
00403 
00404 isc_boolean_t
00405 ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
00406                  isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
00407                  dns_rdataclass_t rdclass, void *arg);
00408 /*%
00409  * Isself callback.
00410  */
00411 
00412 isc_result_t
00413 ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp);
00414 
00415 isc_result_t
00416 ns_client_addopt(ns_client_t *client, dns_message_t *message,
00417                  dns_rdataset_t **opt);
00418 
00419 #endif /* NAMED_CLIENT_H */

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