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