Merge from vendor branch LIBARCHIVE:
[dragonfly.git] / contrib / bind-9.3 / bin / named / include / named / client.h
1 /*
2  * Copyright (C) 2004-2006  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and 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: client.h,v 1.60.2.2.10.12 2006/06/06 00:11:40 marka Exp $ */
19
20 #ifndef NAMED_CLIENT_H
21 #define NAMED_CLIENT_H 1
22
23 /*****
24  ***** Module Info
25  *****/
26
27 /*
28  * Client
29  *
30  * This module defines two objects, ns_client_t and ns_clientmgr_t.
31  *
32  * An ns_client_t object handles incoming DNS requests from clients
33  * on a given network interface.
34  *
35  * Each ns_client_t object can handle only one TCP connection or UDP
36  * request at a time.  Therefore, several ns_client_t objects are
37  * typically created to serve each network interface, e.g., one
38  * for handling TCP requests and a few (one per CPU) for handling
39  * UDP requests.
40  *
41  * Incoming requests are classified as queries, zone transfer
42  * requests, update requests, notify requests, etc, and handed off
43  * to the appropriate request handler.  When the request has been
44  * fully handled (which can be much later), the ns_client_t must be
45  * notified of this by calling one of the following functions
46  * exactly once in the context of its task:
47  *
48  *   ns_client_send()   (sending a non-error response)
49  *   ns_client_sendraw() (sending a raw response)
50  *   ns_client_error()  (sending an error response)
51  *   ns_client_next()   (sending no response)
52  *
53  * This will release any resources used by the request and
54  * and allow the ns_client_t to listen for the next request.
55  *
56  * A ns_clientmgr_t manages a number of ns_client_t objects.
57  * New ns_client_t objects are created by calling
58  * ns_clientmgr_createclients(). They are destroyed by
59  * destroying their manager.
60  */
61
62 /***
63  *** Imports
64  ***/
65
66 #include <isc/buffer.h>
67 #include <isc/magic.h>
68 #include <isc/stdtime.h>
69 #include <isc/quota.h>
70
71 #include <dns/fixedname.h>
72 #include <dns/name.h>
73 #include <dns/rdataclass.h>
74 #include <dns/rdatatype.h>
75 #include <dns/tcpmsg.h>
76 #include <dns/types.h>
77
78 #include <named/types.h>
79 #include <named/query.h>
80
81 /***
82  *** Types
83  ***/
84
85 typedef ISC_LIST(ns_client_t) client_list_t;
86
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         unsigned int            attributes;
101         isc_task_t *            task;
102         dns_view_t *            view;
103         dns_dispatch_t *        dispatch;
104         isc_socket_t *          udpsocket;
105         isc_socket_t *          tcplistener;
106         isc_socket_t *          tcpsocket;
107         unsigned char *         tcpbuf;
108         dns_tcpmsg_t            tcpmsg;
109         isc_boolean_t           tcpmsg_valid;
110         isc_timer_t *           timer;
111         isc_boolean_t           timerset;
112         dns_message_t *         message;
113         isc_socketevent_t *     sendevent;
114         isc_socketevent_t *     recvevent;
115         unsigned char *         recvbuf;
116         dns_rdataset_t *        opt;
117         isc_uint16_t            udpsize;
118         isc_uint16_t            extflags;
119         void                    (*next)(ns_client_t *);
120         void                    (*shutdown)(void *arg, isc_result_t result);
121         void                    *shutdown_arg;
122         ns_query_t              query;
123         isc_stdtime_t           requesttime;
124         isc_stdtime_t           now;
125         dns_name_t              signername;   /* [T]SIG key name */
126         dns_name_t *            signer;       /* NULL if not valid sig */
127         isc_boolean_t           mortal;       /* Die after handling request */
128         isc_quota_t             *tcpquota;
129         isc_quota_t             *recursionquota;
130         ns_interface_t          *interface;
131         isc_sockaddr_t          peeraddr;
132         isc_boolean_t           peeraddr_valid;
133         struct in6_pktinfo      pktinfo;
134         isc_event_t             ctlevent;
135         /*
136          * Information about recent FORMERR response(s), for
137          * FORMERR loop avoidance.  This is separate for each
138          * client object rather than global only to avoid
139          * the need for locking.
140          */
141         struct {
142                 isc_sockaddr_t          addr;
143                 isc_stdtime_t           time;
144                 dns_messageid_t         id;
145         } formerrcache;
146         ISC_LINK(ns_client_t)   link;
147         /*
148          * The list 'link' is part of, or NULL if not on any list.
149          */
150         client_list_t           *list;
151 };
152
153 #define NS_CLIENT_MAGIC                 ISC_MAGIC('N','S','C','c')
154 #define NS_CLIENT_VALID(c)              ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
155
156 #define NS_CLIENTATTR_TCP               0x01
157 #define NS_CLIENTATTR_RA                0x02 /* Client gets recusive service */
158 #define NS_CLIENTATTR_PKTINFO           0x04 /* pktinfo is valid */
159 #define NS_CLIENTATTR_MULTICAST         0x08 /* recv'd from multicast */
160 #define NS_CLIENTATTR_WANTDNSSEC        0x10 /* include dnssec records */
161
162
163 /***
164  *** Functions
165  ***/
166
167 /*
168  * Note!  These ns_client_ routines MUST be called ONLY from the client's
169  * task in order to ensure synchronization.
170  */
171
172 void
173 ns_client_send(ns_client_t *client);
174 /*
175  * Finish processing the current client request and
176  * send client->message as a response.
177  */
178
179 void
180 ns_client_sendraw(ns_client_t *client, dns_message_t *msg);
181 /*
182  * Finish processing the current client request and
183  * send msg as a response using client->message->id for the id.
184  */
185
186 void
187 ns_client_error(ns_client_t *client, isc_result_t result);
188 /*
189  * Finish processing the current client request and return
190  * an error response to the client.  The error response
191  * will have an RCODE determined by 'result'.
192  */
193
194 void
195 ns_client_next(ns_client_t *client, isc_result_t result);
196 /*
197  * Finish processing the current client request,
198  * return no response to the client.
199  */
200
201 void
202 ns_client_qnamereplace(ns_client_t *client, dns_name_t *name);
203 /*%
204  * Replace the qname.
205  */
206
207 isc_boolean_t
208 ns_client_shuttingdown(ns_client_t *client);
209 /*
210  * Return ISC_TRUE iff the client is currently shutting down.
211  */
212
213 void
214 ns_client_attach(ns_client_t *source, ns_client_t **target);
215 /*
216  * Attach '*targetp' to 'source'.
217  */
218
219 void
220 ns_client_detach(ns_client_t **clientp);
221 /*
222  * Detach '*clientp' from its client.
223  */
224
225 isc_result_t
226 ns_client_replace(ns_client_t *client);
227 /*
228  * Try to replace the current client with a new one, so that the
229  * current one can go off and do some lengthy work without
230  * leaving the dispatch/socket without service.
231  */
232
233 void
234 ns_client_settimeout(ns_client_t *client, unsigned int seconds);
235 /*
236  * Set a timer in the client to go off in the specified amount of time.
237  */
238
239 isc_result_t
240 ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
241                     isc_timermgr_t *timermgr, ns_clientmgr_t **managerp);
242 /*
243  * Create a client manager.
244  */
245
246 void
247 ns_clientmgr_destroy(ns_clientmgr_t **managerp);
248 /*
249  * Destroy a client manager and all ns_client_t objects
250  * managed by it.
251  */
252
253 isc_result_t
254 ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
255                            ns_interface_t *ifp, isc_boolean_t tcp);
256 /*
257  * Create up to 'n' clients listening on interface 'ifp'.
258  * If 'tcp' is ISC_TRUE, the clients will listen for TCP connections,
259  * otherwise for UDP requests.
260  */
261
262 isc_sockaddr_t *
263 ns_client_getsockaddr(ns_client_t *client);
264 /*
265  * Get the socket address of the client whose request is
266  * currently being processed.
267  */
268
269 isc_result_t
270 ns_client_checkaclsilent(ns_client_t  *client,dns_acl_t *acl,
271                          isc_boolean_t default_allow);
272
273 /*
274  * Convenience function for client request ACL checking.
275  *
276  * Check the current client request against 'acl'.  If 'acl'
277  * is NULL, allow the request iff 'default_allow' is ISC_TRUE.
278  *
279  * Notes:
280  *      This is appropriate for checking allow-update,
281  *      allow-query, allow-transfer, etc.  It is not appropriate
282  *      for checking the blackhole list because we treat positive
283  *      matches as "allow" and negative matches as "deny"; in
284  *      the case of the blackhole list this would be backwards.
285  *
286  * Requires:
287  *      'client' points to a valid client.
288  *      'acl' points to a valid ACL, or is NULL.
289  *
290  * Returns:
291  *      ISC_R_SUCCESS   if the request should be allowed
292  *      ISC_R_REFUSED   if the request should be denied
293  *      No other return values are possible.
294  */
295
296 isc_result_t
297 ns_client_checkacl(ns_client_t  *client,
298                    const char *opname, dns_acl_t *acl,
299                    isc_boolean_t default_allow,
300                    int log_level);
301 /*
302  * Like ns_client_checkacl, but also logs the outcome of the
303  * check at log level 'log_level' if denied, and at debug 3
304  * if approved.  Log messages will refer to the request as
305  * an 'opname' request.
306  *
307  * Requires:
308  *      Those of ns_client_checkaclsilent(), and:
309  *
310  *      'opname' points to a null-terminated string.
311  */
312
313 void
314 ns_client_log(ns_client_t *client, isc_logcategory_t *category,
315               isc_logmodule_t *module, int level,
316               const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6);
317
318 void
319 ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
320                isc_logmodule_t *module, int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0);
321
322 void
323 ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type,
324                  dns_rdataclass_t rdclass, char *buf, size_t len);
325
326 #define NS_CLIENT_ACLMSGSIZE(x) \
327         (DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \
328          DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'"))
329
330 void
331 ns_client_recursing(ns_client_t *client);
332 /*%
333  * Add client to end of recursing list.  If 'killoldest' is true
334  * kill the oldest recursive client (list head). 
335  */
336
337 void
338 ns_client_killoldestquery(ns_client_t *client);
339 /*%
340  * Kill the oldest recursive query (recursing list head).
341  */
342
343 void
344 ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager);
345 /*
346  * Dump the outstanding recursive queries to 'f'.
347  */
348
349 #endif /* NAMED_CLIENT_H */