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 <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