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
63ISC_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
82struct 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 */
96struct 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
150isc_result_t
151dns_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
172void
173dns_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
183void
184dns_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
195dns_acl_t *
196dns_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
207void
208dns_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
217dns_portlist_t *
218dns_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
226isc_result_t
227dns_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
238void
239dns_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
253isc_result_t
254dns_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
262isc_result_t
263dns_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
295isc_result_t
296dns_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
343void
344dns_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
354void
355dns_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
363void
364dns_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
372isc_result_t
373dns_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
378isc_result_t
379dns_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
419void
420dns_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
435isc_socket_t *
436dns_dispatch_getentrysocket(dns_dispentry_t *resp);
437
438isc_socket_t *
439dns_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
450isc_result_t
451dns_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
465void
466dns_dispatch_cancel(dns_dispatch_t *disp);
467/*%<
468 * cancel outstanding clients
469 *
470 * Requires:
471 *\li	disp is valid.
472 */
473
474unsigned int
475dns_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
484void
485dns_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
509void
510dns_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
521dns_dispatch_t *
522dns_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
531isc_result_t
532dns_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
545void
546dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task);
547/*%<
548 * Cancel socket operations for the dispatches in 'dset'.
549 */
550
551void
552dns_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
561ISC_LANG_ENDDECLS
562
563#endif /* DNS_DISPATCH_H */
564