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