]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/bind9/bin/named/include/named/client.h
MFC r363988:
[FreeBSD/stable/9.git] / contrib / bind9 / bin / named / include / named / client.h
1 /*
2  * Copyright (C) 2004-2009, 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id$ */
19
20 #ifndef NAMED_CLIENT_H
21 #define NAMED_CLIENT_H 1
22
23 /*****
24  ***** Module Info
25  *****/
26
27 /*! \file
28  * \brief
29  * This module defines two objects, ns_client_t and ns_clientmgr_t.
30  *
31  * An ns_client_t object handles incoming DNS requests from clients
32  * on a given network interface.
33  *
34  * Each ns_client_t object can handle only one TCP connection or UDP
35  * request at a time.  Therefore, several ns_client_t objects are
36  * typically created to serve each network interface, e.g., one
37  * for handling TCP requests and a few (one per CPU) for handling
38  * UDP requests.
39  *
40  * Incoming requests are classified as queries, zone transfer
41  * requests, update requests, notify requests, etc, and handed off
42  * to the appropriate request handler.  When the request has been
43  * fully handled (which can be much later), the ns_client_t must be
44  * notified of this by calling one of the following functions
45  * exactly once in the context of its task:
46  * \code
47  *   ns_client_send()   (sending a non-error response)
48  *   ns_client_sendraw() (sending a raw response)
49  *   ns_client_error()  (sending an error response)
50  *   ns_client_next()   (sending no response)
51  *\endcode
52  * This will release any resources used by the request and
53  * and allow the ns_client_t to listen for the next request.
54  *
55  * A ns_clientmgr_t manages a number of ns_client_t objects.
56  * New ns_client_t objects are created by calling
57  * ns_clientmgr_createclients(). They are destroyed by
58  * destroying their manager.
59  */
60
61 /***
62  *** Imports
63  ***/
64
65 #include <isc/buffer.h>
66 #include <isc/magic.h>
67 #include <isc/stdtime.h>
68 #include <isc/quota.h>
69 #include <isc/queue.h>
70
71 #include <dns/db.h>
72 #include <dns/fixedname.h>
73 #include <dns/name.h>
74 #include <dns/rdataclass.h>
75 #include <dns/rdatatype.h>
76 #include <dns/tcpmsg.h>
77 #include <dns/types.h>
78
79 #include <named/types.h>
80 #include <named/query.h>
81
82 /***
83  *** Types
84  ***/
85
86 /*% nameserver client structure */
87 struct ns_client {
88         unsigned int            magic;
89         isc_mem_t *             mctx;
90         ns_clientmgr_t *        manager;
91         int                     state;
92         int                     newstate;
93         int                     naccepts;
94         int                     nreads;
95         int                     nsends;
96         int                     nrecvs;
97         int                     nupdates;
98         int                     nctls;
99         int                     references;
100         isc_boolean_t           needshutdown;   /*
101                                                  * Used by clienttest to get
102                                                  * the client to go from
103                                                  * inactive to free state
104                                                  * by shutting down the
105                                                  * client's task.
106                                                  */
107         unsigned int            attributes;
108         isc_task_t *            task;
109         dns_view_t *            view;
110         dns_dispatch_t *        dispatch;
111         isc_socket_t *          udpsocket;
112         isc_socket_t *          tcplistener;
113         isc_socket_t *          tcpsocket;
114         unsigned char *         tcpbuf;
115         dns_tcpmsg_t            tcpmsg;
116         isc_boolean_t           tcpmsg_valid;
117         isc_timer_t *           timer;
118         isc_boolean_t           timerset;
119         dns_message_t *         message;
120         isc_socketevent_t *     sendevent;
121         isc_socketevent_t *     recvevent;
122         unsigned char *         recvbuf;
123         dns_rdataset_t *        opt;
124         isc_uint16_t            udpsize;
125         isc_uint16_t            extflags;
126         isc_int16_t             ednsversion;    /* -1 noedns */
127         void                    (*next)(ns_client_t *);
128         void                    (*shutdown)(void *arg, isc_result_t result);
129         void                    *shutdown_arg;
130         ns_query_t              query;
131         isc_stdtime_t           requesttime;
132         isc_stdtime_t           now;
133         dns_name_t              signername;   /*%< [T]SIG key name */
134         dns_name_t *            signer;       /*%< NULL if not valid sig */
135         isc_boolean_t           mortal;       /*%< Die after handling request */
136         isc_quota_t             *tcpquota;
137         isc_quota_t             *recursionquota;
138         ns_interface_t          *interface;
139         isc_sockaddr_t          peeraddr;
140         isc_boolean_t           peeraddr_valid;
141         isc_netaddr_t           destaddr;
142         struct in6_pktinfo      pktinfo;
143         isc_event_t             ctlevent;
144 #ifdef ALLOW_FILTER_AAAA_ON_V4
145         dns_v4_aaaa_t           filter_aaaa;
146 #endif
147         /*%
148          * Information about recent FORMERR response(s), for
149          * FORMERR loop avoidance.  This is separate for each
150          * client object rather than global only to avoid
151          * the need for locking.
152          */
153         struct {
154                 isc_sockaddr_t          addr;
155                 isc_stdtime_t           time;
156                 dns_messageid_t         id;
157         } formerrcache;
158
159         ISC_LINK(ns_client_t)   link;
160         ISC_LINK(ns_client_t)   rlink;
161         ISC_QLINK(ns_client_t)  ilink;
162 };
163
164 typedef ISC_QUEUE(ns_client_t) client_queue_t;
165 typedef ISC_LIST(ns_client_t) client_list_t;
166
167 #define NS_CLIENT_MAGIC                 ISC_MAGIC('N','S','C','c')
168 #define NS_CLIENT_VALID(c)              ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
169
170 #define NS_CLIENTATTR_TCP               0x001
171 #define NS_CLIENTATTR_RA                0x002 /*%< Client gets recursive service */
172 #define NS_CLIENTATTR_PKTINFO           0x004 /*%< pktinfo is valid */
173 #define NS_CLIENTATTR_MULTICAST         0x008 /*%< recv'd from multicast */
174 #define NS_CLIENTATTR_WANTDNSSEC        0x010 /*%< include dnssec records */
175 #define NS_CLIENTATTR_WANTNSID          0x020 /*%< include nameserver ID */
176 #ifdef ALLOW_FILTER_AAAA_ON_V4
177 #define NS_CLIENTATTR_FILTER_AAAA       0x040 /*%< suppress AAAAs */
178 #define NS_CLIENTATTR_FILTER_AAAA_RC    0x080 /*%< recursing for A against AAAA */
179 #endif
180 #define NS_CLIENTATTR_WANTAD            0x100 /*%< want AD in response if possible */
181
182 extern unsigned int ns_client_requests;
183
184 /***
185  *** Functions
186  ***/
187
188 /*%
189  * Note!  These ns_client_ routines MUST be called ONLY from the client's
190  * task in order to ensure synchronization.
191  */
192
193 void
194 ns_client_send(ns_client_t *client);
195 /*%
196  * Finish processing the current client request and
197  * send client->message as a response.
198  * \brief
199  * Note!  These ns_client_ routines MUST be called ONLY from the client's
200  * task in order to ensure synchronization.
201  */
202
203 void
204 ns_client_sendraw(ns_client_t *client, dns_message_t *msg);
205 /*%
206  * Finish processing the current client request and
207  * send msg as a response using client->message->id for the id.
208  */
209
210 void
211 ns_client_error(ns_client_t *client, isc_result_t result);
212 /*%
213  * Finish processing the current client request and return
214  * an error response to the client.  The error response
215  * will have an RCODE determined by 'result'.
216  */
217
218 void
219 ns_client_next(ns_client_t *client, isc_result_t result);
220 /*%
221  * Finish processing the current client request,
222  * return no response to the client.
223  */
224
225 isc_boolean_t
226 ns_client_shuttingdown(ns_client_t *client);
227 /*%
228  * Return ISC_TRUE iff the client is currently shutting down.
229  */
230
231 void
232 ns_client_attach(ns_client_t *source, ns_client_t **target);
233 /*%
234  * Attach '*targetp' to 'source'.
235  */
236
237 void
238 ns_client_detach(ns_client_t **clientp);
239 /*%
240  * Detach '*clientp' from its client.
241  */
242
243 isc_result_t
244 ns_client_replace(ns_client_t *client);
245 /*%
246  * Try to replace the current client with a new one, so that the
247  * current one can go off and do some lengthy work without
248  * leaving the dispatch/socket without service.
249  */
250
251 void
252 ns_client_settimeout(ns_client_t *client, unsigned int seconds);
253 /*%
254  * Set a timer in the client to go off in the specified amount of time.
255  */
256
257 isc_result_t
258 ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
259                     isc_timermgr_t *timermgr, ns_clientmgr_t **managerp);
260 /*%
261  * Create a client manager.
262  */
263
264 void
265 ns_clientmgr_destroy(ns_clientmgr_t **managerp);
266 /*%
267  * Destroy a client manager and all ns_client_t objects
268  * managed by it.
269  */
270
271 isc_result_t
272 ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
273                            ns_interface_t *ifp, isc_boolean_t tcp);
274 /*%
275  * Create up to 'n' clients listening on interface 'ifp'.
276  * If 'tcp' is ISC_TRUE, the clients will listen for TCP connections,
277  * otherwise for UDP requests.
278  */
279
280 isc_sockaddr_t *
281 ns_client_getsockaddr(ns_client_t *client);
282 /*%
283  * Get the socket address of the client whose request is
284  * currently being processed.
285  */
286
287 isc_result_t
288 ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
289                          dns_acl_t *acl, isc_boolean_t default_allow);
290
291 /*%
292  * Convenience function for client request ACL checking.
293  *
294  * Check the current client request against 'acl'.  If 'acl'
295  * is NULL, allow the request iff 'default_allow' is ISC_TRUE.
296  * If netaddr is NULL, check the ACL against client->peeraddr;
297  * otherwise check it against netaddr.
298  *
299  * Notes:
300  *\li   This is appropriate for checking allow-update,
301  *      allow-query, allow-transfer, etc.  It is not appropriate
302  *      for checking the blackhole list because we treat positive
303  *      matches as "allow" and negative matches as "deny"; in
304  *      the case of the blackhole list this would be backwards.
305  *
306  * Requires:
307  *\li   'client' points to a valid client.
308  *\li   'netaddr' points to a valid address, or is NULL.
309  *\li   'acl' points to a valid ACL, or is NULL.
310  *
311  * Returns:
312  *\li   ISC_R_SUCCESS   if the request should be allowed
313  * \li  DNS_R_REFUSED   if the request should be denied
314  *\li   No other return values are possible.
315  */
316
317 isc_result_t
318 ns_client_checkacl(ns_client_t  *client,
319                    isc_sockaddr_t *sockaddr,
320                    const char *opname, dns_acl_t *acl,
321                    isc_boolean_t default_allow,
322                    int log_level);
323 /*%
324  * Like ns_client_checkaclsilent, except the outcome of the check is
325  * logged at log level 'log_level' if denied, and at debug 3 if approved.
326  * Log messages will refer to the request as an 'opname' request.
327  *
328  * Requires:
329  *\li   'client' points to a valid client.
330  *\li   'sockaddr' points to a valid address, or is NULL.
331  *\li   'acl' points to a valid ACL, or is NULL.
332  *\li   'opname' points to a null-terminated string.
333  */
334
335 void
336 ns_client_log(ns_client_t *client, isc_logcategory_t *category,
337               isc_logmodule_t *module, int level,
338               const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6);
339
340 void
341 ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
342                isc_logmodule_t *module, int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0);
343
344 void
345 ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type,
346                  dns_rdataclass_t rdclass, char *buf, size_t len);
347
348 #define NS_CLIENT_ACLMSGSIZE(x) \
349         (DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \
350          DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'"))
351
352 void
353 ns_client_recursing(ns_client_t *client);
354 /*%
355  * Add client to end of th recursing list.
356  */
357
358 void
359 ns_client_killoldestquery(ns_client_t *client);
360 /*%
361  * Kill the oldest recursive query (recursing list head).
362  */
363
364 void
365 ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager);
366 /*%
367  * Dump the outstanding recursive queries to 'f'.
368  */
369
370 void
371 ns_client_qnamereplace(ns_client_t *client, dns_name_t *name);
372 /*%
373  * Replace the qname.
374  */
375
376 isc_boolean_t
377 ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
378                  isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
379                  dns_rdataclass_t rdclass, void *arg);
380 /*%
381  * Isself callback.
382  */
383
384 isc_result_t
385 ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp);
386
387 #endif /* NAMED_CLIENT_H */