]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - contrib/bind9/lib/dns/include/dns/dispatch.h
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / contrib / bind9 / lib / dns / include / dns / dispatch.h
1 /*
2  * Copyright (C) 2004, 2005, 2007, 2008  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: dispatch.h,v 1.48.18.9 2008/06/24 23:45:55 tbox Exp $ */
19
20 #ifndef DNS_DISPATCH_H
21 #define DNS_DISPATCH_H 1
22
23 /*****
24  ***** Module Info
25  *****/
26
27 /*! \file
28  * \brief
29  * DNS Dispatch Management
30  *      Shared UDP and single-use TCP dispatches for queries and responses.
31  *
32  * MP:
33  *
34  *\li           All locking is performed internally to each dispatch.
35  *      Restrictions apply to dns_dispatch_removeresponse().
36  *
37  * Reliability:
38  *
39  * Resources:
40  *
41  * Security:
42  *
43  *\li   Depends on the isc_socket_t and dns_message_t for prevention of
44  *      buffer overruns.
45  *
46  * Standards:
47  *
48  *\li   None.
49  */
50
51 /***
52  *** Imports
53  ***/
54
55 #include <isc/buffer.h>
56 #include <isc/lang.h>
57 #include <isc/socket.h>
58 #include <dns/types.h>
59
60 #include <dns/types.h>
61
62 ISC_LANG_BEGINDECLS
63
64 /*%
65  * This event is sent to a task when a response comes in.
66  * No part of this structure should ever be modified by the caller,
67  * other than parts of the buffer.  The holy parts of the buffer are
68  * the base and size of the buffer.  All other parts of the buffer may
69  * be used.  On event delivery the used region contains the packet.
70  *
71  * "id" is the received message id,
72  *
73  * "addr" is the host that sent it to us,
74  *
75  * "buffer" holds state on the received data.
76  *
77  * The "free" routine for this event will clean up itself as well as
78  * any buffer space allocated from common pools.
79  */
80
81 struct dns_dispatchevent {
82         ISC_EVENT_COMMON(dns_dispatchevent_t);  /*%< standard event common */
83         isc_result_t            result;         /*%< result code */
84         isc_int32_t             id;             /*%< message id */
85         isc_sockaddr_t          addr;           /*%< address recv'd from */
86         struct in6_pktinfo      pktinfo;        /*%< reply info for v6 */
87         isc_buffer_t            buffer;         /*%< data buffer */
88         isc_uint32_t            attributes;     /*%< mirrored from socket.h */
89 };
90
91 /*@{*/
92 /*%
93  * Attributes for added dispatchers.
94  *
95  * Values with the mask 0xffff0000 are application defined.
96  * Values with the mask 0x0000ffff are library defined.
97  *
98  * Insane values (like setting both TCP and UDP) are not caught.  Don't
99  * do that.
100  *
101  * _PRIVATE
102  *      The dispatcher cannot be shared.
103  *
104  * _TCP, _UDP
105  *      The dispatcher is a TCP or UDP socket.
106  *
107  * _IPV4, _IPV6
108  *      The dispatcher uses an IPv4 or IPv6 socket.
109  *
110  * _NOLISTEN
111  *      The dispatcher should not listen on the socket.
112  *
113  * _MAKEQUERY
114  *      The dispatcher can be used to issue queries to other servers, and
115  *      accept replies from them.
116  *
117  * _RANDOMPORT
118  *      Previously used to indicate that the port of a dispatch UDP must be
119  *      chosen randomly.  This behavior now always applies and the attribute
120  *      is obsoleted.
121  *
122  * _EXCLUSIVE
123  *      A separate socket will be used on-demand for each transaction.
124  */
125 #define DNS_DISPATCHATTR_PRIVATE        0x00000001U
126 #define DNS_DISPATCHATTR_TCP            0x00000002U
127 #define DNS_DISPATCHATTR_UDP            0x00000004U
128 #define DNS_DISPATCHATTR_IPV4           0x00000008U
129 #define DNS_DISPATCHATTR_IPV6           0x00000010U
130 #define DNS_DISPATCHATTR_NOLISTEN       0x00000020U
131 #define DNS_DISPATCHATTR_MAKEQUERY      0x00000040U
132 #define DNS_DISPATCHATTR_CONNECTED      0x00000080U
133 /*#define DNS_DISPATCHATTR_RANDOMPORT   0x00000100U*/
134 #define DNS_DISPATCHATTR_EXCLUSIVE      0x00000200U
135 /*@}*/
136
137 isc_result_t
138 dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
139                        dns_dispatchmgr_t **mgrp);
140 /*%<
141  * Creates a new dispatchmgr object.
142  *
143  * Requires:
144  *\li   "mctx" be a valid memory context.
145  *
146  *\li   mgrp != NULL && *mgrp == NULL
147  *
148  *\li   "entropy" may be NULL, in which case an insecure random generator
149  *      will be used.  If it is non-NULL, it must be a valid entropy
150  *      source.
151  *
152  * Returns:
153  *\li   ISC_R_SUCCESS   -- all ok
154  *
155  *\li   anything else   -- failure
156  */
157
158
159 void
160 dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp);
161 /*%<
162  * Destroys the dispatchmgr when it becomes empty.  This could be
163  * immediately.
164  *
165  * Requires:
166  *\li   mgrp != NULL && *mgrp is a valid dispatchmgr.
167  */
168
169
170 void
171 dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole);
172 /*%<
173  * Sets the dispatcher's "blackhole list," a list of addresses that will
174  * be ignored by all dispatchers created by the dispatchmgr.
175  *
176  * Requires:
177  * \li  mgrp is a valid dispatchmgr
178  * \li  blackhole is a valid acl
179  */
180
181
182 dns_acl_t *
183 dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr);
184 /*%<
185  * Gets a pointer to the dispatcher's current blackhole list,
186  * without incrementing its reference count.
187  *
188  * Requires:
189  *\li   mgr is a valid dispatchmgr
190  * Returns:
191  *\li   A pointer to the current blackhole list, or NULL.
192  */
193
194 void
195 dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr,
196                                  dns_portlist_t *portlist);
197 /*%<
198  * This function is deprecated.  Use dns_dispatchmgr_setavailports() instead.
199  *
200  * Requires:
201  *\li   mgr is a valid dispatchmgr
202  */
203
204 dns_portlist_t *
205 dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr);
206 /*%<
207  * This function is deprecated and always returns NULL.
208  *
209  * Requires:
210  *\li   mgr is a valid dispatchmgr
211  */
212
213 isc_result_t
214 dns_dispatchmgr_setavailports(dns_dispatchmgr_t *mgr, isc_portset_t *v4portset,
215                               isc_portset_t *v6portset);
216 /*%<
217  * Sets a list of UDP ports that can be used for outgoing UDP messages.
218  *
219  * Requires:
220  *\li   mgr is a valid dispatchmgr
221  *\li   v4portset is NULL or a valid port set
222  *\li   v6portset is NULL or a valid port set
223  */
224
225 isc_result_t
226 dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
227                     isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
228                     unsigned int buffersize,
229                     unsigned int maxbuffers, unsigned int maxrequests,
230                     unsigned int buckets, unsigned int increment,
231                     unsigned int attributes, unsigned int mask,
232                     dns_dispatch_t **dispp);
233 /*%<
234  * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find,
235  * otherwise create a new UDP dispatch.
236  *
237  * Requires:
238  *\li   All pointer parameters be valid for their respective types.
239  *
240  *\li   dispp != NULL && *disp == NULL
241  *
242  *\li   512 <= buffersize <= 64k
243  *
244  *\li   maxbuffers > 0
245  *
246  *\li   buckets < 2097169
247  *
248  *\li   increment > buckets
249  *
250  *\li   (attributes & DNS_DISPATCHATTR_TCP) == 0
251  *
252  * Returns:
253  *\li   ISC_R_SUCCESS   -- success.
254  *
255  *\li   Anything else   -- failure.
256  */
257
258 isc_result_t
259 dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
260                        isc_taskmgr_t *taskmgr, unsigned int buffersize,
261                        unsigned int maxbuffers, unsigned int maxrequests,
262                        unsigned int buckets, unsigned int increment,
263                        unsigned int attributes, dns_dispatch_t **dispp);
264 /*%<
265  * Create a new dns_dispatch and attach it to the provided isc_socket_t.
266  *
267  * For all dispatches, "buffersize" is the maximum packet size we will
268  * accept.
269  *
270  * "maxbuffers" and "maxrequests" control the number of buffers in the
271  * overall system and the number of buffers which can be allocated to
272  * requests.
273  *
274  * "buckets" is the number of buckets to use, and should be prime.
275  *
276  * "increment" is used in a collision avoidance function, and needs to be
277  * a prime > buckets, and not 2.
278  *
279  * Requires:
280  *
281  *\li   mgr is a valid dispatch manager.
282  *
283  *\li   sock is a valid.
284  *
285  *\li   task is a valid task that can be used internally to this dispatcher.
286  *
287  * \li  512 <= buffersize <= 64k
288  *
289  *\li   maxbuffers > 0.
290  *
291  *\li   maxrequests <= maxbuffers.
292  *
293  *\li   buckets < 2097169 (the next prime after 65536 * 32)
294  *
295  *\li   increment > buckets (and prime).
296  *
297  *\li   attributes includes #DNS_DISPATCHATTR_TCP and does not include
298  *      #DNS_DISPATCHATTR_UDP.
299  *
300  * Returns:
301  *\li   ISC_R_SUCCESS   -- success.
302  *
303  *\li   Anything else   -- failure.
304  */
305
306 void
307 dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp);
308 /*%<
309  * Attach to a dispatch handle.
310  *
311  * Requires:
312  *\li   disp is valid.
313  *
314  *\li   dispp != NULL && *dispp == NULL
315  */
316
317 void
318 dns_dispatch_detach(dns_dispatch_t **dispp);
319 /*%<
320  * Detaches from the dispatch.
321  *
322  * Requires:
323  *\li   dispp != NULL and *dispp be a valid dispatch.
324  */
325
326 void
327 dns_dispatch_starttcp(dns_dispatch_t *disp);
328 /*%<
329  * Start processing of a TCP dispatch once the socket connects.
330  *
331  * Requires:
332  *\li   'disp' is valid.
333  */
334
335 isc_result_t
336 dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
337                           isc_task_t *task, isc_taskaction_t action, void *arg,
338                           isc_uint16_t *idp, dns_dispentry_t **resp,
339                           isc_socketmgr_t *sockmgr);
340
341 isc_result_t
342 dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
343                          isc_task_t *task, isc_taskaction_t action, void *arg,
344                          isc_uint16_t *idp, dns_dispentry_t **resp);
345 /*%<
346  * Add a response entry for this dispatch.
347  *
348  * "*idp" is filled in with the assigned message ID, and *resp is filled in
349  * to contain the magic token used to request event flow stop.
350  *
351  * Arranges for the given task to get a callback for response packets.  When
352  * the event is delivered, it must be returned using dns_dispatch_freeevent()
353  * or through dns_dispatch_removeresponse() for another to be delivered.
354  *
355  * Requires:
356  *\li   "idp" be non-NULL.
357  *
358  *\li   "task" "action" and "arg" be set as appropriate.
359  *
360  *\li   "dest" be non-NULL and valid.
361  *
362  *\li   "resp" be non-NULL and *resp be NULL
363  *
364  *\li   "sockmgr" be NULL or a valid socket manager.  If 'disp' has
365  *      the DNS_DISPATCHATTR_EXCLUSIVE attribute, this must not be NULL,
366  *      which also means dns_dispatch_addresponse() cannot be used.
367  *
368  * Ensures:
369  *
370  *\li   &lt;id, dest> is a unique tuple.  That means incoming messages
371  *      are identifiable.
372  *
373  * Returns:
374  *
375  *\li   ISC_R_SUCCESS           -- all is well.
376  *\li   ISC_R_NOMEMORY          -- memory could not be allocated.
377  *\li   ISC_R_NOMORE            -- no more message ids can be allocated
378  *                                 for this destination.
379  */
380
381
382 void
383 dns_dispatch_removeresponse(dns_dispentry_t **resp,
384                             dns_dispatchevent_t **sockevent);
385 /*%<
386  * Stops the flow of responses for the provided id and destination.
387  * If "sockevent" is non-NULL, the dispatch event and associated buffer is
388  * also returned to the system.
389  *
390  * Requires:
391  *\li   "resp" != NULL and "*resp" contain a value previously allocated
392  *      by dns_dispatch_addresponse();
393  *
394  *\li   May only be called from within the task given as the 'task'
395  *      argument to dns_dispatch_addresponse() when allocating '*resp'.
396  */
397
398 isc_socket_t *
399 dns_dispatch_getentrysocket(dns_dispentry_t *resp);
400
401 isc_socket_t *
402 dns_dispatch_getsocket(dns_dispatch_t *disp);
403 /*%<
404  * Return the socket associated with this dispatcher.
405  *
406  * Requires:
407  *\li   disp is valid.
408  *
409  * Returns:
410  *\li   The socket the dispatcher is using.
411  */
412
413 isc_result_t
414 dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp);
415 /*%<
416  * Return the local address for this dispatch.
417  * This currently only works for dispatches using UDP sockets.
418  *
419  * Requires:
420  *\li   disp is valid.
421  *\li   addrp to be non null.
422  *
423  * Returns:
424  *\li   ISC_R_SUCCESS
425  *\li   ISC_R_NOTIMPLEMENTED
426  */
427
428 void
429 dns_dispatch_cancel(dns_dispatch_t *disp);
430 /*%<
431  * cancel outstanding clients
432  *
433  * Requires:
434  *\li   disp is valid.
435  */
436
437 unsigned int
438 dns_dispatch_getattributes(dns_dispatch_t *disp);
439 /*%<
440  * Return the attributes (DNS_DISPATCHATTR_xxx) of this dispatch.  Only the
441  * non-changeable attributes are expected to be referenced by the caller.
442  *
443  * Requires:
444  *\li   disp is valid.
445  */
446
447 void
448 dns_dispatch_changeattributes(dns_dispatch_t *disp,
449                               unsigned int attributes, unsigned int mask);
450 /*%<
451  * Set the bits described by "mask" to the corresponding values in
452  * "attributes".
453  *
454  * That is:
455  *
456  * \code
457  *      new = (old & ~mask) | (attributes & mask)
458  * \endcode
459  *
460  * This function has a side effect when #DNS_DISPATCHATTR_NOLISTEN changes.
461  * When the flag becomes off, the dispatch will start receiving on the
462  * corresponding socket.  When the flag becomes on, receive events on the
463  * corresponding socket will be canceled.
464  *
465  * Requires:
466  *\li   disp is valid.
467  *
468  *\li   attributes are reasonable for the dispatch.  That is, setting the UDP
469  *      attribute on a TCP socket isn't reasonable.
470  */
471
472 void
473 dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event);
474 /*%<
475  * Inform the dispatcher of a socket receive.  This is used for sockets
476  * shared between dispatchers and clients.  If the dispatcher fails to copy
477  * or send the event, nothing happens.
478  *
479  * Requires:
480  *\li   disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set.
481  *      event != NULL
482  */
483
484 ISC_LANG_ENDDECLS
485
486 #endif /* DNS_DISPATCH_H */