dispatch.h revision 0c27b3fe77ac1d5094ba3521e8142d9e7973133f
/*
* Copyright (C) 1999-2009, 2011-2016 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef DNS_DISPATCH_H
#define DNS_DISPATCH_H 1
/*****
***** Module Info
*****/
/*! \file dns/dispatch.h
* \brief
* DNS Dispatch Management
* Shared UDP and single-use TCP dispatches for queries and responses.
*
* MP:
*
*\li All locking is performed internally to each dispatch.
* Restrictions apply to dns_dispatch_removeresponse().
*
* Reliability:
*
* Resources:
*
* Security:
*
*\li Depends on the isc_socket_t and dns_message_t for prevention of
* buffer overruns.
*
* Standards:
*
*\li None.
*/
/***
*** Imports
***/
/*%
* This event is sent to a task when a response comes in.
* 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.
*/
struct dns_dispatchevent {
};
/*%
* This is a set of one or more dispatches which can be retrieved
* round-robin fashion.
*/
struct dns_dispatchset {
int ndisp;
int cur;
};
/*@{*/
/*%
* 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.
*
* _NOLISTEN
* The dispatcher should not listen on the socket.
*
* _MAKEQUERY
* The dispatcher can be used to issue queries to other servers, and
* accept replies from them.
*
* _RANDOMPORT
* Previously used to indicate that the port of a dispatch UDP must be
* chosen randomly. This behavior now always applies and the attribute
* is obsoleted.
*
* _EXCLUSIVE
* A separate socket will be used on-demand for each transaction.
*/
#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
#define DNS_DISPATCHATTR_NOLISTEN 0x00000020U
#define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U
#define DNS_DISPATCHATTR_CONNECTED 0x00000080U
#define DNS_DISPATCHATTR_FIXEDID 0x00000100U
#define DNS_DISPATCHATTR_EXCLUSIVE 0x00000200U
/*@}*/
/*
*/
#define DNS_DISPATCHOPT_FIXEDID 0x00000001U
/*%<
* Creates a new dispatchmgr object.
*
* Requires:
*\li "mctx" be a valid memory context.
*
*\li mgrp != NULL && *mgrp == NULL
*
*\li "entropy" may be NULL, in which case an insecure random generator
* will be used. If it is non-NULL, it must be a valid entropy
* source.
*
* Returns:
*\li ISC_R_SUCCESS -- all ok
*
*\li anything else -- failure
*/
void
/*%<
* Destroys the dispatchmgr when it becomes empty. This could be
* immediately.
*
* Requires:
*\li mgrp != NULL && *mgrp is a valid dispatchmgr.
*/
void
/*%<
* Sets the dispatcher's "blackhole list," a list of addresses that will
* be ignored by all dispatchers created by the dispatchmgr.
*
* Requires:
* \li mgrp is a valid dispatchmgr
* \li blackhole is a valid acl
*/
/*%<
* Gets a pointer to the dispatcher's current blackhole list,
* without incrementing its reference count.
*
* Requires:
*\li mgr is a valid dispatchmgr
* Returns:
*\li A pointer to the current blackhole list, or NULL.
*/
void
/*%<
* This function is deprecated. Use dns_dispatchmgr_setavailports() instead.
*
* Requires:
*\li mgr is a valid dispatchmgr
*/
/*%<
* This function is deprecated and always returns NULL.
*
* Requires:
*\li mgr is a valid dispatchmgr
*/
/*%<
* Sets a list of UDP ports that can be used for outgoing UDP messages.
*
* Requires:
*\li mgr is a valid dispatchmgr
*\li v4portset is NULL or a valid port set
*\li v6portset is NULL or a valid port set
*/
void
/*%<
* Sets statistics counter for the dispatchmgr. This function is expected to
* be called only on zone creation (when necessary).
* Once installed, it cannot be removed or replaced. Also, there is no
* interface to get the installed stats from the zone; the caller must keep the
* stats to reference (e.g. dump) it later.
*
* Requires:
*\li mgr is a valid dispatchmgr with no managed dispatch.
*\li stats is a valid statistics supporting resolver statistics counters
*/
unsigned int buffersize,
unsigned int maxbuffers, unsigned int maxrequests,
unsigned int attributes, unsigned int mask,
dns_dispatch_t **dispp);
unsigned int buffersize,
unsigned int maxbuffers, unsigned int maxrequests,
unsigned int attributes, unsigned int mask,
/*%<
* Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find,
* otherwise create a new UDP dispatch.
*
* Requires:
*\li All pointer parameters be valid for their respective types.
*
*\li dispp != NULL && *disp == NULL
*
*\li 512 <= buffersize <= 64k
*
*\li maxbuffers > 0
*
*\li buckets < 2097169
*
*\li increment > buckets
*
*\li (attributes & DNS_DISPATCHATTR_TCP) == 0
*
* Returns:
*\li ISC_R_SUCCESS -- success.
*
*\li Anything else -- failure.
*/
unsigned int maxbuffers, unsigned int maxrequests,
unsigned int maxbuffers, unsigned int maxrequests,
/*%<
* Create a new dns_dispatch and attach it to the provided isc_socket_t.
*
* For all dispatches, "buffersize" is the maximum packet size we will
* accept.
*
* "maxbuffers" and "maxrequests" control the number of buffers in the
* overall system and the number of buffers which can be allocated to
* requests.
*
* "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.
*
* Requires:
*
*\li mgr is a valid dispatch manager.
*
*\li sock is a valid.
*
*\li task is a valid task that can be used internally to this dispatcher.
*
* \li 512 <= buffersize <= 64k
*
*\li maxbuffers > 0.
*
*\li maxrequests <= maxbuffers.
*
*\li buckets < 2097169 (the next prime after 65536 * 32)
*
*\li increment > buckets (and prime).
*
*\li attributes includes #DNS_DISPATCHATTR_TCP and does not include
* #DNS_DISPATCHATTR_UDP.
*
* Returns:
*\li ISC_R_SUCCESS -- success.
*
*\li Anything else -- failure.
*/
void
/*%<
* Attach to a dispatch handle.
*
* Requires:
*\li disp is valid.
*
*\li dispp != NULL && *dispp == NULL
*/
void
/*%<
* Detaches from the dispatch.
*
* Requires:
*\li dispp != NULL and *dispp be a valid dispatch.
*/
void
/*%<
* Start processing of a TCP dispatch once the socket connects.
*
* Requires:
*\li 'disp' is valid.
*/
dns_dispatch_t **dispp);
/*
* Attempt to connect to a existing TCP connection (connection completed
* for dns_dispatch_gettcp()).
*/
/*%<
* Add a response entry for this dispatch.
*
* "*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.
*
* 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.
*
* Requires:
*\li "idp" be non-NULL.
*
*\li "task" "action" and "arg" be set as appropriate.
*
*\li "dest" be non-NULL and valid.
*
*\li "resp" be non-NULL and *resp be NULL
*
*\li "sockmgr" be NULL or a valid socket manager. If 'disp' has
* the DNS_DISPATCHATTR_EXCLUSIVE attribute, this must not be NULL,
* which also means dns_dispatch_addresponse() cannot be used.
*
* Ensures:
*
*\li <id, dest> is a unique tuple. That means incoming messages
* are identifiable.
*
* Returns:
*
*\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
* for this destination.
*/
void
/*%<
* Stops the flow of responses for the provided id and destination.
* If "sockevent" is non-NULL, the dispatch event and associated buffer is
* also returned to the system.
*
* Requires:
*\li "resp" != NULL and "*resp" contain a value previously allocated
* by dns_dispatch_addresponse();
*
*\li May only be called from within the task given as the 'task'
* argument to dns_dispatch_addresponse() when allocating '*resp'.
*/
/*%<
* Return the socket associated with this dispatcher.
*
* Requires:
*\li disp is valid.
*
* Returns:
*\li The socket the dispatcher is using.
*/
/*%<
* Return the local address for this dispatch.
* This currently only works for dispatches using UDP sockets.
*
* Requires:
*\li disp is valid.
*\li addrp to be non null.
*
* Returns:
*\li ISC_R_SUCCESS
*\li ISC_R_NOTIMPLEMENTED
*/
void
/*%<
* cancel outstanding clients
*
* Requires:
*\li disp is valid.
*/
unsigned int
/*%<
* Return the attributes (DNS_DISPATCHATTR_xxx) of this dispatch. Only the
* non-changeable attributes are expected to be referenced by the caller.
*
* Requires:
*\li disp is valid.
*/
void
unsigned int attributes, unsigned int mask);
/*%<
* Set the bits described by "mask" to the corresponding values in
* "attributes".
*
* That is:
*
* \code
* new = (old & ~mask) | (attributes & mask)
* \endcode
*
* This function has a side effect when #DNS_DISPATCHATTR_NOLISTEN changes.
* 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.
*
* Requires:
*\li disp is valid.
*
*\li attributes are reasonable for the dispatch. That is, setting the UDP
* attribute on a TCP socket isn't reasonable.
*/
void
/*%<
* 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.
*
* Requires:
*\li disp is valid, and the attribute DNS_DISPATCHATTR_NOLISTEN is set.
* event != NULL
*/
/*%<
* Retrieve the next dispatch from dispatch set 'dset', and increment
* the round-robin counter.
*
* Requires:
*\li dset != NULL
*/
dns_dispatchset_t **dsetp, int n);
/*%<
* Given a valid dispatch 'source', create a dispatch set containing
* 'n' UDP dispatches, with the remainder filled out by clones of the
* source.
*
* Requires:
*\li source is a valid UDP dispatcher
*\li dsetp != NULL, *dsetp == NULL
*/
void
/*%<
* Cancel socket operations for the dispatches in 'dset'.
*/
void
/*%<
* Dereference all the dispatches in '*dsetp', free the dispatchset
* memory, and set *dsetp to NULL.
*
* Requires:
*\li dset is valid
*/
void
/*%<
* as defined in the "listen-on" or "listen-on-v6" statements.
*
* Requires:
*\li disp is valid.
*/
#endif /* DNS_DISPATCH_H */