1/*
2 * Copyright (C) 2004-2009, 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$ */
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
62ISC_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
81struct 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
137isc_result_t
138dns_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
159void
160dns_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
170void
171dns_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
182dns_acl_t *
183dns_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
194void
195dns_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
204dns_portlist_t *
205dns_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
213isc_result_t
214dns_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
225void
226dns_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
240isc_result_t
241dns_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
273isc_result_t
274dns_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
321void
322dns_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
332void
333dns_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
341void
342dns_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
350isc_result_t
351dns_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
356isc_result_t
357dns_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
397void
398dns_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
413isc_socket_t *
414dns_dispatch_getentrysocket(dns_dispentry_t *resp);
415
416isc_socket_t *
417dns_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
428isc_result_t
429dns_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
443void
444dns_dispatch_cancel(dns_dispatch_t *disp);
445/*%<
446 * cancel outstanding clients
447 *
448 * Requires:
449 *\li	disp is valid.
450 */
451
452unsigned int
453dns_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
462void
463dns_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
487void
488dns_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
499ISC_LANG_ENDDECLS
500
501#endif /* DNS_DISPATCH_H */
502