7d0f361f9b9b15cc8912718ee796eb39f8a26538
[dragonfly.git] / contrib / bind-9.5.2 / lib / dns / include / dns / dispatch.h
1 /*
2  * Copyright (C) 2004-2009  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.56.128.7 2009/01/29 23:47:13 tbox Exp $ */
19
20 #ifndef DNS_DISPATCH_H
21 #define DNS_DISPATCH_H 1
22
23 /*****
24  ***** Module Info
25  *****/
26
27 /*! \file dns/dispatch.h
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 <isc/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 void
226 dns_dispatchmgr_setstats(dns_dispatchmgr_t *mgr, isc_stats_t *stats);
227 /*%<
228  * Sets statistics counter for the dispatchmgr.  This function is expected to
229  * be called only on zone creation (when necessary).
230  * Once installed, it cannot be removed or replaced.  Also, there is no
231  * interface to get the installed stats from the zone; the caller must keep the
232  * stats to reference (e.g. dump) it later.
233  *
234  * Requires:
235  *\li   mgr is a valid dispatchmgr with no managed dispatch.
236  *\li   stats is a valid statistics supporting resolver statistics counters
237  *      (see dns/stats.h).
238  */
239
240 isc_result_t
241 dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
242                     isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
243                     unsigned int buffersize,
244                     unsigned int maxbuffers, unsigned int maxrequests,
245                     unsigned int buckets, unsigned int increment,
246                     unsigned int attributes, unsigned int mask,
247                     dns_dispatch_t **dispp);
248 /*%<
249  * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find,
250  * otherwise create a new UDP dispatch.
251  *
252  * Requires:
253  *\li   All pointer parameters be valid for their respective types.
254  *
255  *\li   dispp != NULL && *disp == NULL
256  *
257  *\li   512 <= buffersize <= 64k
258  *
259  *\li   maxbuffers > 0
260  *
261  *\li   buckets < 2097169
262  *
263  *\li   increment > buckets
264  *
265  *\li   (attributes & DNS_DISPATCHATTR_TCP) == 0
266  *
267  * Returns:
268  *\li   ISC_R_SUCCESS   -- success.
269  *
270  *\li   Anything else   -- failure.
271  */
272
273 isc_result_t
274 dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
275                        isc_taskmgr_t *taskmgr, unsigned int buffersize,
276                        unsigned int maxbuffers, unsigned int maxrequests,
277                        unsigned int buckets, unsigned int increment,
278                        unsigned int attributes, dns_dispatch_t **dispp);
279 /*%<
280  * Create a new dns_dispatch and attach it to the provided isc_socket_t.
281  *
282  * For all dispatches, "buffersize" is the maximum packet size we will
283  * accept.
284  *
285  * "maxbuffers" and "maxrequests" control the number of buffers in the
286  * overall system and the number of buffers which can be allocated to
287  * requests.
288  *
289  * "buckets" is the number of buckets to use, and should be prime.
290  *
291  * "increment" is used in a collision avoidance function, and needs to be
292  * a prime > buckets, and not 2.
293  *
294  * Requires:
295  *
296  *\li   mgr is a valid dispatch manager.
297  *
298  *\li   sock is a valid.
299  *
300  *\li   task is a valid task that can be used internally to this dispatcher.
301  *
302  * \li  512 <= buffersize <= 64k
303  *
304  *\li   maxbuffers > 0.
305  *
306  *\li   maxrequests <= maxbuffers.
307  *
308  *\li   buckets < 2097169 (the next prime after 65536 * 32)
309  *
310  *\li   increment > buckets (and prime).
311  *
312  *\li   attributes includes #DNS_DISPATCHATTR_TCP and does not include
313  *      #DNS_DISPATCHATTR_UDP.
314  *
315  * Returns:
316  *\li   ISC_R_SUCCESS   -- success.
317  *
318  *\li   Anything else   -- failure.
319  */
320
321 void
322 dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp);
323 /*%<
324  * Attach to a dispatch handle.
325  *
326  * Requires:
327  *\li   disp is valid.
328  *
329  *\li   dispp != NULL && *dispp == NULL
330  */
331
332 void
333 dns_dispatch_detach(dns_dispatch_t **dispp);
334 /*%<
335  * Detaches from the dispatch.
336  *
337  * Requires:
338  *\li   dispp != NULL and *dispp be a valid dispatch.
339  */
340
341 void
342 dns_dispatch_starttcp(dns_dispatch_t *disp);
343 /*%<
344  * Start processing of a TCP dispatch once the socket connects.
345  *
346  * Requires:
347  *\li   'disp' is valid.
348  */
349
350 isc_result_t
351 dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
352                           isc_task_t *task, isc_taskaction_t action, void *arg,
353                           isc_uint16_t *idp, dns_dispentry_t **resp,
354                           isc_socketmgr_t *sockmgr);
355
356 isc_result_t
357 dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
358                          isc_task_t *task, isc_taskaction_t action, void *arg,
359                          isc_uint16_t *idp, dns_dispentry_t **resp);
360 /*%<
361  * Add a response entry for this dispatch.
362  *
363  * "*idp" is filled in with the assigned message ID, and *resp is filled in
364  * to contain the magic token used to request event flow stop.
365  *
366  * Arranges for the given task to get a callback for response packets.  When
367  * the event is delivered, it must be returned using dns_dispatch_freeevent()
368  * or through dns_dispatch_removeresponse() for another to be delivered.
369  *
370  * Requires:
371  *\li   "idp" be non-NULL.
372  *
373  *\li   "task" "action" and "arg" be set as appropriate.
374  *
375  *\li   "dest" be non-NULL and valid.
376  *
377  *\li   "resp" be non-NULL and *resp be NULL
378  *
379  *\li   "sockmgr" be NULL or a valid socket manager.  If 'disp' has
380  *      the DNS_DISPATCHATTR_EXCLUSIVE attribute, this must not be NULL,
381  *      which also means dns_dispatch_addresponse() cannot be used.
382  *
383  * Ensures:
384  *
385  *\li   &lt;id, dest> is a unique tuple.  That means incoming messages
386  *      are identifiable.
387  *
388  * Returns:
389  *
390  *\li   ISC_R_SUCCESS           -- all is well.
391  *\li   ISC_R_NOMEMORY          -- memory could not be allocated.
392  *\li   ISC_R_NOMORE            -- no more message ids can be allocated
393  *                                 for this destination.
394  */
395
396
397 void
398 dns_dispatch_removeresponse(dns_dispentry_t **resp,
399                             dns_dispatchevent_t **sockevent);
400 /*%<
401  * Stops the flow of responses for the provided id and destination.
402  * If "sockevent" is non-NULL, the dispatch event and associated buffer is
403  * also returned to the system.
404  *
405  * Requires:
406  *\li   "resp" != NULL and "*resp" contain a value previously allocated
407  *      by dns_dispatch_addresponse();
408  *
409  *\li   May only be called from within the task given as the 'task'
410  *      argument to dns_dispatch_addresponse() when allocating '*resp'.
411  */
412
413 isc_socket_t *
414 dns_dispatch_getentrysocket(dns_dispentry_t *resp);
415
416 isc_socket_t *
417 dns_dispatch_getsocket(dns_dispatch_t *disp);
418 /*%<
419  * Return the socket associated with this dispatcher.
420  *
421  * Requires:
422  *\li   disp is valid.
423  *
424  * Returns:
425  *\li   The socket the dispatcher is using.
426  */
427
428 isc_result_t
429 dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp);
430 /*%<
431  * Return the local address for this dispatch.
432  * This currently only works for dispatches using UDP sockets.
433  *
434  * Requires:
435  *\li   disp is valid.
436  *\li   addrp to be non null.
437  *
438  * Returns:
439  *\li   ISC_R_SUCCESS
440  *\li   ISC_R_NOTIMPLEMENTED
441  */
442
443 void
444 dns_dispatch_cancel(dns_dispatch_t *disp);
445 /*%<
446  * cancel outstanding clients
447  *
448  * Requires:
449  *\li   disp is valid.
450  */
451
452 unsigned int
453 dns_dispatch_getattributes(dns_dispatch_t *disp);
454 /*%<
455  * Return the attributes (DNS_DISPATCHATTR_xxx) of this dispatch.  Only the
456  * non-changeable attributes are expected to be referenced by the caller.
457  *
458  * Requires:
459  *\li   disp is valid.
460  */
461
462 void
463 dns_dispatch_changeattributes(dns_dispatch_t *disp,
464                               unsigned int attributes, unsigned int mask);
465 /*%<
466  * Set the bits described by "mask" to the corresponding values in
467  * "attributes".
468  *
469  * That is:
470  *
471  * \code
472  *      new = (old & ~mask) | (attributes & mask)
473  * \endcode
474  *
475  * This function has a side effect when #DNS_DISPATCHATTR_NOLISTEN changes.
476  * When the flag becomes off, the dispatch will start receiving on the
477  * corresponding socket.  When the flag becomes on, receive events on the
478  * corresponding socket will be canceled.
479  *
480  * Requires:
481  *\li   disp is valid.
482  *
483  *\li   attributes are reasonable for the dispatch.  That is, setting the UDP
484  *      attribute on a TCP socket isn't reasonable.
485  */
486
487 void
488 dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event);
489 /*%<
490  * Inform the dispatcher of a socket receive.  This is used for sockets
491  * shared between dispatchers and clients.  If the dispatcher fails to copy
492  * or send the event, nothing happens.
493  *
494  * Requires:
495  *\li   disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set.
496  *      event != NULL
497  */
498
499 ISC_LANG_ENDDECLS
500
501 #endif /* DNS_DISPATCH_H */