dispatch.h 11.4 KB
Newer Older
Michael Graff's avatar
Michael Graff committed
1
/*
Mark Andrews's avatar
Mark Andrews committed
2
 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
Mark Andrews's avatar
Mark Andrews committed
3
 * Copyright (C) 1999-2003  Internet Software Consortium.
4
 *
Michael Graff's avatar
Michael Graff committed
5 6 7
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
8
 *
Mark Andrews's avatar
Mark Andrews committed
9 10 11 12 13 14 15
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
Michael Graff's avatar
Michael Graff committed
16 17
 */

Mark Andrews's avatar
Mark Andrews committed
18
/* $Id: dispatch.h,v 1.54 2007/02/06 00:01:23 marka Exp $ */
David Lawrence's avatar
David Lawrence committed
19

20 21
#ifndef DNS_DISPATCH_H
#define DNS_DISPATCH_H 1
Michael Graff's avatar
Michael Graff committed
22 23 24 25 26

/*****
 ***** Module Info
 *****/

27
/*! \file dns/dispatch.h
28
 * \brief
29 30
 * DNS Dispatch Management
 * 	Shared UDP and single-use TCP dispatches for queries and responses.
Michael Graff's avatar
Michael Graff committed
31 32 33
 *
 * MP:
 *
34
 *\li     	All locking is performed internally to each dispatch.
35
 * 	Restrictions apply to dns_dispatch_removeresponse().
Michael Graff's avatar
Michael Graff committed
36 37 38 39 40 41 42
 *
 * Reliability:
 *
 * Resources:
 *
 * Security:
 *
43
 *\li	Depends on the isc_socket_t and dns_message_t for prevention of
Michael Graff's avatar
Michael Graff committed
44 45 46 47
 *	buffer overruns.
 *
 * Standards:
 *
48
 *\li	None.
Michael Graff's avatar
Michael Graff committed
49 50 51 52 53 54 55 56
 */

/***
 *** Imports
 ***/

#include <isc/buffer.h>
#include <isc/lang.h>
Bob Halley's avatar
Bob Halley committed
57
#include <isc/socket.h>
58
#include <dns/types.h>
Michael Graff's avatar
Michael Graff committed
59 60 61 62 63

#include <dns/types.h>

ISC_LANG_BEGINDECLS

64
/*%
65
 * This event is sent to a task when a response comes in.
Michael Graff's avatar
Michael Graff committed
66 67 68 69 70 71 72 73 74 75 76 77 78 79
 * No part of this structure should ever be modified by the caller,
 * other than parts of the buffer.  The holy parts of the buffer are
 * the base and size of the buffer.  All other parts of the buffer may
 * be used.  On event delivery the used region contains the packet.
 *
 * "id" is the received message id,
 *
 * "addr" is the host that sent it to us,
 *
 * "buffer" holds state on the received data.
 *
 * The "free" routine for this event will clean up itself as well as
 * any buffer space allocated from common pools.
 */
Bob Halley's avatar
Bob Halley committed
80

Michael Graff's avatar
Michael Graff committed
81
struct dns_dispatchevent {
82 83 84 85 86 87 88
	ISC_EVENT_COMMON(dns_dispatchevent_t);	/*%< standard event common */
	isc_result_t		result;		/*%< result code */
	isc_int32_t		id;		/*%< message id */
	isc_sockaddr_t		addr;		/*%< address recv'd from */
	struct in6_pktinfo	pktinfo;	/*%< reply info for v6 */
	isc_buffer_t	        buffer;		/*%< data buffer */
	isc_uint32_t		attributes;	/*%< mirrored from socket.h */
Michael Graff's avatar
Michael Graff committed
89 90
};

91 92
/*@{*/
/*%
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
 * Attributes for added dispatchers.
 *
 * Values with the mask 0xffff0000 are application defined.
 * Values with the mask 0x0000ffff are library defined.
 *
 * Insane values (like setting both TCP and UDP) are not caught.  Don't
 * do that.
 *
 * _PRIVATE
 *	The dispatcher cannot be shared.
 *
 * _TCP, _UDP
 *	The dispatcher is a TCP or UDP socket.
 *
 * _IPV4, _IPV6
 *	The dispatcher uses an ipv4 or ipv6 socket.
 *
110 111
 * _NOLISTEN
 *	The dispatcher should not listen on the socket.
112
 *
113
 * _MAKEQUERY
114 115
 *	The dispatcher can be used to issue queries to other servers, and
 *	accept replies from them.
116 117 118
 *
 * _RANDOMPORT
 *	TBD
119 120 121 122 123 124
 */
#define DNS_DISPATCHATTR_PRIVATE	0x00000001U
#define DNS_DISPATCHATTR_TCP		0x00000002U
#define DNS_DISPATCHATTR_UDP		0x00000004U
#define DNS_DISPATCHATTR_IPV4		0x00000008U
#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
129
/*@}*/
130

Michael Graff's avatar
Michael Graff committed
131
isc_result_t
132 133
dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
		       dns_dispatchmgr_t **mgrp);
134
/*%<
135 136 137
 * Creates a new dispatchmgr object.
 *
 * Requires:
138
 *\li	"mctx" be a valid memory context.
139
 *
140
 *\li	mgrp != NULL && *mgrp == NULL
141
 *
142
 *\li	"entropy" may be NULL, in which case an insecure random generator
143 144 145
 *	will be used.  If it is non-NULL, it must be a valid entropy
 *	source.
 *
146
 * Returns:
147
 *\li	ISC_R_SUCCESS	-- all ok
148
 *
149
 *\li	anything else	-- failure
150 151 152 153 154
 */


void
dns_dispatchmgr_destroy(dns_dispatchmgr_t **mgrp);
155
/*%<
156 157 158 159
 * Destroys the dispatchmgr when it becomes empty.  This could be
 * immediately.
 *
 * Requires:
160
 *\li	mgrp != NULL && *mgrp is a valid dispatchmgr.
161 162 163
 */


164 165
void
dns_dispatchmgr_setblackhole(dns_dispatchmgr_t *mgr, dns_acl_t *blackhole);
166
/*%<
167 168
 * Sets the dispatcher's "blackhole list," a list of addresses that will
 * be ignored by all dispatchers created by the dispatchmgr.
169 170
 *
 * Requires:
171 172
 * \li	mgrp is a valid dispatchmgr
 * \li	blackhole is a valid acl
173 174 175
 */


176 177
dns_acl_t *
dns_dispatchmgr_getblackhole(dns_dispatchmgr_t *mgr);
178
/*%<
179 180
 * Gets a pointer to the dispatcher's current blackhole list,
 * without incrementing its reference count.
181 182
 *
 * Requires:
183
 *\li 	mgr is a valid dispatchmgr
184
 * Returns:
185
 *\li	A pointer to the current blackhole list, or NULL.
186 187
 */

188 189 190
void
dns_dispatchmgr_setblackportlist(dns_dispatchmgr_t *mgr,
                                 dns_portlist_t *portlist);
191
/*%<
192 193 194 195
 * Sets a list of UDP ports that won't be used when creating a udp
 * dispatch with a wildcard port.
 *
 * Requires:
196 197
 *\li	mgr is a valid dispatchmgr
 *\li	portlist to be NULL or a valid port list.
198 199 200 201
 */

dns_portlist_t *
dns_dispatchmgr_getblackportlist(dns_dispatchmgr_t *mgr);
202
/*%<
203 204 205
 * Return the current port list.
 *
 * Requires:
206
 *\li	mgr is a valid dispatchmgr
207 208 209
 */


210 211

isc_result_t
212 213 214
dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
		    isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr,
		    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);
219
/*%<
220
 * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find,
221
 * otherwise create a new UDP dispatch.
222 223
 *
 * Requires:
224
 *\li	All pointer parameters be valid for their respective types.
225
 *
226
 *\li	dispp != NULL && *disp == NULL
227
 *
228
 *\li	512 <= buffersize <= 64k
229
 *
230
 *\li	maxbuffers > 0
231
 *
232
 *\li	buckets < 2097169
233
 *
234
 *\li	increment > buckets
235
 *
236
 *\li	(attributes & DNS_DISPATCHATTR_TCP) == 0
237 238
 *
 * Returns:
239
 *\li	ISC_R_SUCCESS	-- success.
240
 *
241
 *\li	Anything else	-- failure.
242
 */
243 244 245 246 247 248 249

isc_result_t
dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
		       isc_taskmgr_t *taskmgr, unsigned int buffersize,
		       unsigned int maxbuffers, unsigned int maxrequests,
		       unsigned int buckets, unsigned int increment,
		       unsigned int attributes, dns_dispatch_t **dispp);
250
/*%<
251
 * Create a new dns_dispatch and attach it to the provided isc_socket_t.
Michael Graff's avatar
Michael Graff committed
252
 *
253
 * For all dispatches, "buffersize" is the maximum packet size we will
Michael Graff's avatar
Michael Graff committed
254
 * accept.
Michael Graff's avatar
Michael Graff committed
255 256 257 258 259
 *
 * "maxbuffers" and "maxrequests" control the number of buffers in the
 * overall system and the number of buffers which can be allocated to
 * requests.
 *
260 261 262 263
 * "buckets" is the number of buckets to use, and should be prime.
 *
 * "increment" is used in a collision avoidance function, and needs to be
 * a prime > buckets, and not 2.
Michael Graff's avatar
Michael Graff committed
264
 *
Michael Graff's avatar
Michael Graff committed
265 266
 * Requires:
 *
267
 *\li	mgr is a valid dispatch manager.
Michael Graff's avatar
Michael Graff committed
268
 *
269
 *\li	sock is a valid.
Michael Graff's avatar
Michael Graff committed
270
 *
271
 *\li	task is a valid task that can be used internally to this dispatcher.
Michael Graff's avatar
Michael Graff committed
272
 *
273
 * \li	512 <= buffersize <= 64k
Michael Graff's avatar
Michael Graff committed
274
 *
275
 *\li	maxbuffers > 0.
Michael Graff's avatar
Michael Graff committed
276
 *
277
 *\li	maxrequests <= maxbuffers.
Michael Graff's avatar
Michael Graff committed
278
 *
279
 *\li	buckets < 2097169 (the next prime after 65536 * 32)
280
 *
281
 *\li	increment > buckets (and prime).
282
 *
283 284
 *\li	attributes includes #DNS_DISPATCHATTR_TCP and does not include
 *	#DNS_DISPATCHATTR_UDP.
285 286
 *
 * Returns:
287
 *\li	ISC_R_SUCCESS	-- success.
288
 *
289
 *\li	Anything else	-- failure.
Michael Graff's avatar
Michael Graff committed
290 291 292
 */

void
293
dns_dispatch_attach(dns_dispatch_t *disp, dns_dispatch_t **dispp);
294
/*%<
295 296 297
 * Attach to a dispatch handle.
 *
 * Requires:
298
 *\li	disp is valid.
299
 *
300
 *\li	dispp != NULL && *dispp == NULL
301 302 303 304
 */

void
dns_dispatch_detach(dns_dispatch_t **dispp);
305
/*%<
306
 * Detaches from the dispatch.
Michael Graff's avatar
Michael Graff committed
307 308
 *
 * Requires:
309
 *\li	dispp != NULL and *dispp be a valid dispatch.
Michael Graff's avatar
Michael Graff committed
310 311
 */

312
void
313
dns_dispatch_starttcp(dns_dispatch_t *disp);
314
/*%<
Mark Andrews's avatar
Mark Andrews committed
315
 * Start processing of a TCP dispatch once the socket connects.
316 317
 *
 * Requires:
318
 *\li	'disp' is valid.
319
 */
320

Michael Graff's avatar
Michael Graff committed
321
isc_result_t
Michael Graff's avatar
Michael Graff committed
322
dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
323
			 isc_task_t *task, isc_taskaction_t action, void *arg,
Michael Graff's avatar
Michael Graff committed
324
			 isc_uint16_t *idp, dns_dispentry_t **resp);
325
/*%<
326
 * Add a response entry for this dispatch.
Michael Graff's avatar
Michael Graff committed
327
 *
Michael Graff's avatar
Michael Graff committed
328 329
 * "*idp" is filled in with the assigned message ID, and *resp is filled in
 * to contain the magic token used to request event flow stop.
Michael Graff's avatar
Michael Graff committed
330
 *
Michael Graff's avatar
Michael Graff committed
331 332 333
 * Arranges for the given task to get a callback for response packets.  When
 * the event is delivered, it must be returned using dns_dispatch_freeevent()
 * or through dns_dispatch_removeresponse() for another to be delivered.
Michael Graff's avatar
Michael Graff committed
334 335
 *
 * Requires:
336
 *\li	"idp" be non-NULL.
Michael Graff's avatar
Michael Graff committed
337
 *
338
 *\li	"task" "action" and "arg" be set as appropriate.
Michael Graff's avatar
Michael Graff committed
339
 *
340
 *\li	"dest" be non-NULL and valid.
Michael Graff's avatar
Michael Graff committed
341
 *
342
 *\li	"resp" be non-NULL and *resp be NULL
Michael Graff's avatar
Michael Graff committed
343 344 345
 *
 * Ensures:
 *
346
 *\li	&lt;id, dest> is a unique tuple.  That means incoming messages
Michael Graff's avatar
Michael Graff committed
347 348 349
 *	are identifiable.
 *
 * Returns:
Michael Graff's avatar
Michael Graff committed
350
 *
351 352 353
 *\li	ISC_R_SUCCESS		-- all is well.
 *\li	ISC_R_NOMEMORY		-- memory could not be allocated.
 *\li	ISC_R_NOMORE		-- no more message ids can be allocated
Michael Graff's avatar
Michael Graff committed
354
 *				   for this destination.
Michael Graff's avatar
Michael Graff committed
355 356
 */

357

Michael Graff's avatar
Michael Graff committed
358
void
359
dns_dispatch_removeresponse(dns_dispentry_t **resp,
Michael Graff's avatar
Michael Graff committed
360
			    dns_dispatchevent_t **sockevent);
361
/*%<
Michael Graff's avatar
Michael Graff committed
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
Michael Graff's avatar
Michael Graff committed
364 365 366
 * also returned to the system.
 *
 * Requires:
367
 *\li	"resp" != NULL and "*resp" contain a value previously allocated
Michael Graff's avatar
Michael Graff committed
368
 *	by dns_dispatch_addresponse();
369
 *
370
 *\li	May only be called from within the task given as the 'task' 
371
 * 	argument to dns_dispatch_addresponse() when allocating '*resp'.
Michael Graff's avatar
Michael Graff committed
372 373
 */

374

375 376
isc_socket_t *
dns_dispatch_getsocket(dns_dispatch_t *disp);
377
/*%<
378 379 380
 * Return the socket associated with this dispatcher.
 *
 * Requires:
381
 *\li	disp is valid.
382 383
 *
 * Returns:
384
 *\li	The socket the dispatcher is using.
385 386
 */

387 388
isc_result_t 
dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp);
389
/*%<
390 391 392 393
 * Return the local address for this dispatch.
 * This currently only works for dispatches using UDP sockets.
 *
 * Requires:
394 395
 *\li	disp is valid.
 *\li	addrp to be non null.
396 397
 *
 * Returns:
398 399
 *\li	ISC_R_SUCCESS	
 *\li	ISC_R_NOTIMPLEMENTED
400
 */
401

Michael Graff's avatar
Michael Graff committed
402 403
void
dns_dispatch_cancel(dns_dispatch_t *disp);
404
/*%<
Michael Graff's avatar
Michael Graff committed
405
 * cancel outstanding clients
406 407
 *
 * Requires:
408
 *\li	disp is valid.
409 410 411 412 413
 */

void
dns_dispatch_changeattributes(dns_dispatch_t *disp,
			      unsigned int attributes, unsigned int mask);
414
/*%<
415 416 417
 * Set the bits described by "mask" to the corresponding values in
 * "attributes".
 *
418
 * That is:
419
 *
420
 * \code
421
 *	new = (old & ~mask) | (attributes & mask)
422
 * \endcode
423
 *
424
 * This function has a side effect when #DNS_DISPATCHATTR_NOLISTEN changes. 
425 426 427 428
 * When the flag becomes off, the dispatch will start receiving on the
 * corresponding socket.  When the flag becomes on, receive events on the
 * corresponding socket will be canceled.
 *
429
 * Requires:
430
 *\li	disp is valid.
431
 *
432
 *\li	attributes are reasonable for the dispatch.  That is, setting the UDP
433
 *	attribute on a TCP socket isn't reasonable.
Michael Graff's avatar
Michael Graff committed
434 435
 */

436
void
437
dns_dispatch_importrecv(dns_dispatch_t *disp, isc_event_t *event);
438
/*%<
439 440 441
 * Inform the dispatcher of a socket receive.  This is used for sockets
 * shared between dispatchers and clients.  If the dispatcher fails to copy
 * or send the event, nothing happens.
442 443
 *
 * Requires:
444
 *\li 	disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set.
445
 * 	event != NULL
446 447
 */

Michael Graff's avatar
Michael Graff committed
448 449
ISC_LANG_ENDDECLS

450
#endif /* DNS_DISPATCH_H */