Merge from vendor branch LIBARCHIVE:
[dragonfly.git] / contrib / bind-9.3 / lib / dns / include / dns / dispatch.h
1 /*
2  * Copyright (C) 2004  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: dispatch.h,v 1.45.2.2.4.2.26.1 2007/06/26 04:14:56 marka Exp $ */
19
20 #ifndef DNS_DISPATCH_H
21 #define DNS_DISPATCH_H 1
22
23 /*****
24  ***** Module Info
25  *****/
26
27 /*
28  * DNS Dispatch Management
29  *
30  *      Shared UDP and single-use TCP dispatches for queries and responses.
31  *
32  * MP:
33  *
34  *      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  *      Depends on the isc_socket_t and dns_message_t for prevention of
44  *      buffer overruns.
45  *
46  * Standards:
47  *
48  *      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  * Attributes for added dispatchers.
93  *
94  * Values with the mask 0xffff0000 are application defined.
95  * Values with the mask 0x0000ffff are library defined.
96  *
97  * Insane values (like setting both TCP and UDP) are not caught.  Don't
98  * do that.
99  *
100  * _PRIVATE
101  *      The dispatcher cannot be shared.
102  *
103  * _TCP, _UDP
104  *      The dispatcher is a TCP or UDP socket.
105  *
106  * _IPV4, _IPV6
107  *      The dispatcher uses an ipv4 or ipv6 socket.
108  *
109  * _NOLISTEN
110  *      The dispatcher should not listen on the socket.
111  *
112  * _MAKEQUERY
113  *      The dispatcher can be used to issue queries to other servers, and
114  *      accept replies from them.
115  */
116 #define DNS_DISPATCHATTR_PRIVATE        0x00000001U
117 #define DNS_DISPATCHATTR_TCP            0x00000002U
118 #define DNS_DISPATCHATTR_UDP            0x00000004U
119 #define DNS_DISPATCHATTR_IPV4           0x00000008U
120 #define DNS_DISPATCHATTR_IPV6           0x00000010U
121 #define DNS_DISPATCHATTR_NOLISTEN       0x00000020U
122 #define DNS_DISPATCHATTR_MAKEQUERY      0x00000040U
123 #define DNS_DISPATCHATTR_CONNECTED      0x00000080U
124
125 isc_result_t
126 dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
127                        dns_dispatchmgr_t **mgrp);
128 /*
129  * Creates a new dispatchmgr object.
130  *
131  * Requires:
132  *      "mctx" be a valid memory context.
133  *
134  *      mgrp != NULL && *mgrp == NULL
135  *
136  *      "entropy" may be NULL, in which case an insecure random generator
137  *      will be used.  If it is non-NULL, it must be a valid entropy
138  *      source.
139  *
140  * Returns:
141  *      ISC_R_SUCCESS   -- all ok
142  *
143  *      anything else   -- failure
144  */
145
146
147 void
148 dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp);
149 /*
150  * Destroys the dispatchmgr when it becomes empty.  This could be
151  * immediately.
152  *
153  * Requires:
154  *      mgrp != NULL && *mgrp is a valid dispatchmgr.
155  */
156
157
158 void
159 dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole);
160 /*
161  * Sets the dispatcher's "blackhole list," a list of addresses that will
162  * be ignored by all dispatchers created by the dispatchmgr.
163  *
164  * Requires:
165  *      mgrp is a valid dispatchmgr
166  *      blackhole is a valid acl
167  */
168
169
170 dns_acl_t *
171 dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr);
172 /*
173  * Gets a pointer to the dispatcher's current blackhole list,
174  * without incrementing its reference count.
175  *
176  * Requires:
177  *      mgr is a valid dispatchmgr
178  * Returns:
179  *      A pointer to the current blackhole list, or NULL.
180  */
181
182 void
183 dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr,
184                                  dns_portlist_t *portlist);
185 /*
186  * Sets a list of UDP ports that won't be used when creating a udp
187  * dispatch with a wildcard port.
188  *
189  * Requires:
190  *      mgr is a valid dispatchmgr
191  *      portlist to be NULL or a valid port list.
192  */
193
194 dns_portlist_t *
195 dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr);
196 /*
197  * Return the current port list.
198  *
199  * Requires:
200  *      mgr is a valid dispatchmgr
201  */
202
203
204
205 isc_result_t
206 dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
207                     isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
208                     unsigned int buffersize,
209                     unsigned int maxbuffers, unsigned int maxrequests,
210                     unsigned int buckets, unsigned int increment,
211                     unsigned int attributes, unsigned int mask,
212                     dns_dispatch_t **dispp);
213 /*
214  * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find,
215  * otherwise create a new UDP dispatch.
216  *
217  * Requires:
218  *      All pointer parameters be valid for their respective types.
219  *
220  *      dispp != NULL && *disp == NULL
221  *
222  *      512 <= buffersize <= 64k
223  *
224  *      maxbuffers > 0
225  *
226  *      buckets < 2097169
227  *
228  *      increment > buckets
229  *
230  *      (attributes & DNS_DISPATCHATTR_TCP) == 0
231  *
232  * Returns:
233  *      ISC_R_SUCCESS   -- success.
234  *
235  *      Anything else   -- failure.
236  */
237
238 isc_result_t
239 dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
240                        isc_taskmgr_t *taskmgr, unsigned int buffersize,
241                        unsigned int maxbuffers, unsigned int maxrequests,
242                        unsigned int buckets, unsigned int increment,
243                        unsigned int attributes, dns_dispatch_t **dispp);
244 /*
245  * Create a new dns_dispatch and attach it to the provided isc_socket_t.
246  *
247  * For all dispatches, "buffersize" is the maximum packet size we will
248  * accept.
249  *
250  * "maxbuffers" and "maxrequests" control the number of buffers in the
251  * overall system and the number of buffers which can be allocated to
252  * requests.
253  *
254  * "buckets" is the number of buckets to use, and should be prime.
255  *
256  * "increment" is used in a collision avoidance function, and needs to be
257  * a prime > buckets, and not 2.
258  *
259  * Requires:
260  *
261  *      mgr is a valid dispatch manager.
262  *
263  *      sock is a valid.
264  *
265  *      task is a valid task that can be used internally to this dispatcher.
266  *
267  *      512 <= buffersize <= 64k
268  *
269  *      maxbuffers > 0.
270  *
271  *      maxrequests <= maxbuffers.
272  *
273  *      buckets < 2097169 (the next prime after 65536 * 32)
274  *
275  *      increment > buckets (and prime).
276  *
277  *      attributes includes DNS_DISPATCHATTR_TCP and does not include
278  *      DNS_DISPATCHATTR_UDP.
279  *
280  * Returns:
281  *      ISC_R_SUCCESS   -- success.
282  *
283  *      Anything else   -- failure.
284  */
285
286 void
287 dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp);
288 /*
289  * Attach to a dispatch handle.
290  *
291  * Requires:
292  *      disp is valid.
293  *
294  *      dispp != NULL && *dispp == NULL
295  */
296
297 void
298 dns_dispatch_detach(dns_dispatch_t **dispp);
299 /*
300  * Detaches from the dispatch.
301  *
302  * Requires:
303  *      dispp != NULL and *dispp be a valid dispatch.
304  */
305
306 void
307 dns_dispatch_starttcp(dns_dispatch_t *disp);
308 /*
309  * Start processing of a TCP dispatch once the socket connects.
310  *
311  * Requires:
312  *      'disp' is valid.
313  */
314
315 isc_result_t
316 dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
317                          isc_task_t *task, isc_taskaction_t action, void *arg,
318                          isc_uint16_t *idp, dns_dispentry_t **resp);
319 /*
320  * Add a response entry for this dispatch.
321  *
322  * "*idp" is filled in with the assigned message ID, and *resp is filled in
323  * to contain the magic token used to request event flow stop.
324  *
325  * Arranges for the given task to get a callback for response packets.  When
326  * the event is delivered, it must be returned using dns_dispatch_freeevent()
327  * or through dns_dispatch_removeresponse() for another to be delivered.
328  *
329  * Requires:
330  *      "idp" be non-NULL.
331  *
332  *      "task" "action" and "arg" be set as appropriate.
333  *
334  *      "dest" be non-NULL and valid.
335  *
336  *      "resp" be non-NULL and *resp be NULL
337  *
338  * Ensures:
339  *
340  *      <id, dest> is a unique tuple.  That means incoming messages
341  *      are identifiable.
342  *
343  * Returns:
344  *
345  *      ISC_R_SUCCESS           -- all is well.
346  *      ISC_R_NOMEMORY          -- memory could not be allocated.
347  *      ISC_R_NOMORE            -- no more message ids can be allocated
348  *                                 for this destination.
349  */
350
351
352 void
353 dns_dispatch_removeresponse(dns_dispentry_t **resp,
354                             dns_dispatchevent_t **sockevent);
355 /*
356  * Stops the flow of responses for the provided id and destination.
357  * If "sockevent" is non-NULL, the dispatch event and associated buffer is
358  * also returned to the system.
359  *
360  * Requires:
361  *      "resp" != NULL and "*resp" contain a value previously allocated
362  *      by dns_dispatch_addresponse();
363  *
364  *      May only be called from within the task given as the 'task' 
365  *      argument to dns_dispatch_addresponse() when allocating '*resp'.
366  */
367
368
369 isc_socket_t *
370 dns_dispatch_getsocket(dns_dispatch_t *disp);
371 /*
372  * Return the socket associated with this dispatcher.
373  *
374  * Requires:
375  *      disp is valid.
376  *
377  * Returns:
378  *      The socket the dispatcher is using.
379  */
380
381 isc_result_t 
382 dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp);
383 /*
384  * Return the local address for this dispatch.
385  * This currently only works for dispatches using UDP sockets.
386  *
387  * Requires:
388  *      disp is valid.
389  *      addrp to be non null.
390  *
391  * Returns:
392  *      ISC_R_SUCCESS   
393  *      ISC_R_NOTIMPLEMENTED
394  */
395
396 void
397 dns_dispatch_cancel(dns_dispatch_t *disp);
398 /*
399  * cancel outstanding clients
400  *
401  * Requires:
402  *      disp is valid.
403  */
404
405 void
406 dns_dispatch_changeattributes(dns_dispatch_t *disp,
407                               unsigned int attributes, unsigned int mask);
408 /*
409  * Set the bits described by "mask" to the corresponding values in
410  * "attributes".
411  *
412  * That is:
413  *
414  *      new = (old & ~mask) | (attributes & mask)
415  *
416  * This function has a side effect when DNS_DISPATCHATTR_NOLISTEN changes. 
417  * When the flag becomes off, the dispatch will start receiving on the
418  * corresponding socket.  When the flag becomes on, receive events on the
419  * corresponding socket will be canceled.
420  *
421  * Requires:
422  *      disp is valid.
423  *
424  *      attributes are reasonable for the dispatch.  That is, setting the UDP
425  *      attribute on a TCP socket isn't reasonable.
426  */
427
428 void
429 dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event);
430 /*
431  * Inform the dispatcher of a socket receive.  This is used for sockets
432  * shared between dispatchers and clients.  If the dispatcher fails to copy
433  * or send the event, nothing happens.
434  *
435  * Requires:
436  *      disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set.
437  *      event != NULL
438  */
439
440 void
441 dns_dispatch_hash(void *data, size_t len);
442 /*%<
443  * Feed 'data' to the dispatch query id generator where 'len' is the size
444  * of 'data'.
445  */
446
447 ISC_LANG_ENDDECLS
448
449 #endif /* DNS_DISPATCH_H */