2 * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
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.
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.
18 /* $Id: dispatch.h,v 1.48.18.5.12.2 2008/07/23 07:28:56 tbox Exp $ */
20 #ifndef DNS_DISPATCH_H
21 #define DNS_DISPATCH_H 1
29 * DNS Dispatch Management
30 * Shared UDP and single-use TCP dispatches for queries and responses.
34 *\li All locking is performed internally to each dispatch.
35 * Restrictions apply to dns_dispatch_removeresponse().
43 *\li Depends on the isc_socket_t and dns_message_t for prevention of
55 #include <isc/buffer.h>
57 #include <isc/socket.h>
58 #include <dns/types.h>
60 #include <dns/types.h>
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.
71 * "id" is the received message id,
73 * "addr" is the host that sent it to us,
75 * "buffer" holds state on the received data.
77 * The "free" routine for this event will clean up itself as well as
78 * any buffer space allocated from common pools.
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 */
93 * Attributes for added dispatchers.
95 * Values with the mask 0xffff0000 are application defined.
96 * Values with the mask 0x0000ffff are library defined.
98 * Insane values (like setting both TCP and UDP) are not caught. Don't
102 * The dispatcher cannot be shared.
105 * The dispatcher is a TCP or UDP socket.
108 * The dispatcher uses an ipv4 or ipv6 socket.
111 * The dispatcher should not listen on the socket.
114 * The dispatcher can be used to issue queries to other servers, and
115 * accept replies from them.
118 * Allocate UDP port randomly.
120 #define DNS_DISPATCHATTR_PRIVATE 0x00000001U
121 #define DNS_DISPATCHATTR_TCP 0x00000002U
122 #define DNS_DISPATCHATTR_UDP 0x00000004U
123 #define DNS_DISPATCHATTR_IPV4 0x00000008U
124 #define DNS_DISPATCHATTR_IPV6 0x00000010U
125 #define DNS_DISPATCHATTR_NOLISTEN 0x00000020U
126 #define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U
127 #define DNS_DISPATCHATTR_CONNECTED 0x00000080U
128 #define DNS_DISPATCHATTR_RANDOMPORT 0x00000100U
132 dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
133 dns_dispatchmgr_t **mgrp);
135 * Creates a new dispatchmgr object.
138 *\li "mctx" be a valid memory context.
140 *\li mgrp != NULL && *mgrp == NULL
142 *\li "entropy" may be NULL, in which case an insecure random generator
143 * will be used. If it is non-NULL, it must be a valid entropy
147 *\li ISC_R_SUCCESS -- all ok
149 *\li anything else -- failure
154 dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp);
156 * Destroys the dispatchmgr when it becomes empty. This could be
160 *\li mgrp != NULL && *mgrp is a valid dispatchmgr.
165 dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole);
167 * Sets the dispatcher's "blackhole list," a list of addresses that will
168 * be ignored by all dispatchers created by the dispatchmgr.
171 * \li mgrp is a valid dispatchmgr
172 * \li blackhole is a valid acl
177 dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr);
179 * Gets a pointer to the dispatcher's current blackhole list,
180 * without incrementing its reference count.
183 *\li mgr is a valid dispatchmgr
185 *\li A pointer to the current blackhole list, or NULL.
189 dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr,
190 dns_portlist_t *portlist);
192 * Sets a list of UDP ports that won't be used when creating a udp
193 * dispatch with a wildcard port.
196 *\li mgr is a valid dispatchmgr
197 *\li portlist to be NULL or a valid port list.
201 dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr);
203 * Return the current port list.
206 *\li mgr is a valid dispatchmgr
212 dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
213 isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
214 unsigned int buffersize,
215 unsigned int maxbuffers, unsigned int maxrequests,
216 unsigned int buckets, unsigned int increment,
217 unsigned int attributes, unsigned int mask,
218 dns_dispatch_t **dispp);
220 * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find,
221 * otherwise create a new UDP dispatch.
224 *\li All pointer parameters be valid for their respective types.
226 *\li dispp != NULL && *disp == NULL
228 *\li 512 <= buffersize <= 64k
232 *\li buckets < 2097169
234 *\li increment > buckets
236 *\li (attributes & DNS_DISPATCHATTR_TCP) == 0
239 *\li ISC_R_SUCCESS -- success.
241 *\li Anything else -- failure.
245 dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
246 isc_taskmgr_t *taskmgr, unsigned int buffersize,
247 unsigned int maxbuffers, unsigned int maxrequests,
248 unsigned int buckets, unsigned int increment,
249 unsigned int attributes, dns_dispatch_t **dispp);
251 * Create a new dns_dispatch and attach it to the provided isc_socket_t.
253 * For all dispatches, "buffersize" is the maximum packet size we will
256 * "maxbuffers" and "maxrequests" control the number of buffers in the
257 * overall system and the number of buffers which can be allocated to
260 * "buckets" is the number of buckets to use, and should be prime.
262 * "increment" is used in a collision avoidance function, and needs to be
263 * a prime > buckets, and not 2.
267 *\li mgr is a valid dispatch manager.
269 *\li sock is a valid.
271 *\li task is a valid task that can be used internally to this dispatcher.
273 * \li 512 <= buffersize <= 64k
277 *\li maxrequests <= maxbuffers.
279 *\li buckets < 2097169 (the next prime after 65536 * 32)
281 *\li increment > buckets (and prime).
283 *\li attributes includes #DNS_DISPATCHATTR_TCP and does not include
284 * #DNS_DISPATCHATTR_UDP.
287 *\li ISC_R_SUCCESS -- success.
289 *\li Anything else -- failure.
293 dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp);
295 * Attach to a dispatch handle.
300 *\li dispp != NULL && *dispp == NULL
304 dns_dispatch_detach(dns_dispatch_t **dispp);
306 * Detaches from the dispatch.
309 *\li dispp != NULL and *dispp be a valid dispatch.
313 dns_dispatch_starttcp(dns_dispatch_t *disp);
315 * Start processing of a TCP dispatch once the socket connects.
318 *\li 'disp' is valid.
322 dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
323 isc_task_t *task, isc_taskaction_t action, void *arg,
324 isc_uint16_t *idp, dns_dispentry_t **resp);
326 * Add a response entry for this dispatch.
328 * "*idp" is filled in with the assigned message ID, and *resp is filled in
329 * to contain the magic token used to request event flow stop.
331 * Arranges for the given task to get a callback for response packets. When
332 * the event is delivered, it must be returned using dns_dispatch_freeevent()
333 * or through dns_dispatch_removeresponse() for another to be delivered.
336 *\li "idp" be non-NULL.
338 *\li "task" "action" and "arg" be set as appropriate.
340 *\li "dest" be non-NULL and valid.
342 *\li "resp" be non-NULL and *resp be NULL
346 *\li <id, dest> is a unique tuple. That means incoming messages
351 *\li ISC_R_SUCCESS -- all is well.
352 *\li ISC_R_NOMEMORY -- memory could not be allocated.
353 *\li ISC_R_NOMORE -- no more message ids can be allocated
354 * for this destination.
359 dns_dispatch_removeresponse(dns_dispentry_t **resp,
360 dns_dispatchevent_t **sockevent);
362 * Stops the flow of responses for the provided id and destination.
363 * If "sockevent" is non-NULL, the dispatch event and associated buffer is
364 * also returned to the system.
367 *\li "resp" != NULL and "*resp" contain a value previously allocated
368 * by dns_dispatch_addresponse();
370 *\li May only be called from within the task given as the 'task'
371 * argument to dns_dispatch_addresponse() when allocating '*resp'.
376 dns_dispatch_getsocket(dns_dispatch_t *disp);
378 * Return the socket associated with this dispatcher.
384 *\li The socket the dispatcher is using.
388 dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp);
390 * Return the local address for this dispatch.
391 * This currently only works for dispatches using UDP sockets.
395 *\li addrp to be non null.
399 *\li ISC_R_NOTIMPLEMENTED
403 dns_dispatch_cancel(dns_dispatch_t *disp);
405 * cancel outstanding clients
412 dns_dispatch_changeattributes(dns_dispatch_t *disp,
413 unsigned int attributes, unsigned int mask);
415 * Set the bits described by "mask" to the corresponding values in
421 * new = (old & ~mask) | (attributes & mask)
424 * This function has a side effect when #DNS_DISPATCHATTR_NOLISTEN changes.
425 * When the flag becomes off, the dispatch will start receiving on the
426 * corresponding socket. When the flag becomes on, receive events on the
427 * corresponding socket will be canceled.
432 *\li attributes are reasonable for the dispatch. That is, setting the UDP
433 * attribute on a TCP socket isn't reasonable.
437 dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event);
439 * Inform the dispatcher of a socket receive. This is used for sockets
440 * shared between dispatchers and clients. If the dispatcher fails to copy
441 * or send the event, nothing happens.
444 *\li disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set.
450 #endif /* DNS_DISPATCH_H */