client.c revision 3f9f14055b85c2dda341b341de0e65d4639542c5
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Copyright (C) 1999-2003 Internet Software Consortium.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Permission to use, copy, modify, and/or distribute this software for any
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * purpose with or without fee is hereby granted, provided that the above
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * copyright notice and this permission notice appear in all copies.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * PERFORMANCE OF THIS SOFTWARE.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews/* $Id: client.c,v 1.267 2010/09/13 03:37:43 marka Exp $ */
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Client Routines
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Important note!
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * All client state changes, other than that from idle to listening, occur
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * as a result of events. This guarantees serialization and avoids the
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * need for locking.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * If a routine is ever created that allows someone other than the client's
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * task to change the client, then the client will have to be locked.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews#define CTRACE(m) ((void)(m))
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews#define MTRACE(m) ((void)(m))
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Number of 'mctx pools' for clients. (Should this be configurable?)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * When enabling threads, we use a pool of memory contexts shared by
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * client objects, since concurrent access to a shared context would cause
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * heavy contentions. The above constant is expected to be enough for
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * completely avoiding contentions among threads for an authoritative-only
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * If named with built without thread, simply share manager's context. Using
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * a separate context in this case would simply waste memory.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews/*% nameserver client manager structure */
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /* Unlocked. */
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews unsigned int magic;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /* Locked by lock. */
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews client_list_t recursing; /*%< Recursing clients */
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews /*%< mctx pool for clients. */
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews unsigned int nextmctx;
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews#define MANAGER_MAGIC ISC_MAGIC('N', 'S', 'C', 'm')
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, MANAGER_MAGIC)
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Client object states. Ordering is significant: higher-numbered
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * states are generally "more active", meaning that the client can
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * have more dynamically allocated data, outstanding events, etc.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * In the list below, any such properties listed for state N
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * also apply to any state > N.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * To force the client into a less active state, set client->newstate
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * to that state and call exit_check(). This will cause any
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * activities defined for higher-numbered states to be aborted.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * The client object no longer exists.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * The client object exists and has a task and timer.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Its "query" struct and sendbuf are initialized.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * It is on the client manager's list of inactive clients.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * It has a message and OPT, both in the reset state.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * The client object is either a TCP or a UDP one, and
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * it is associated with a network interface. It is on the
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * client manager's list of active clients.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * If it is a TCP client object, it has a TCP listener socket
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * and an outstanding TCP listen request.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * If it is a UDP client object, it has a UDP listener socket
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * and an outstanding UDP receive request.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * The client object is a TCP client object that has received
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * a connection. It has a tcpsocket, tcpmsg, TCP quota, and an
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * outstanding TCP read request. This state is not used for
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * UDP client objects.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * The client object has received a request and is working
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * on it. It has a view, and it may have any of a non-reset OPT,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * recursion quota, and an outstanding write request.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Sentinel value used to indicate "no state". When client->newstate
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * has this value, we are not attempting to exit the current state.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Must be greater than any valid state.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Enable ns_client_dropport() by default.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsstatic void client_udprecv(ns_client_t *client);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void clientmgr_destroy(ns_clientmgr_t *manager);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic isc_boolean_t exit_check(ns_client_t *client);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void ns_client_endrequest(ns_client_t *client);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void ns_client_checkactive(ns_client_t *client);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsstatic void client_start(isc_task_t *task, isc_event_t *event);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsstatic void client_request(isc_task_t *task, isc_event_t *event);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsstatic void ns_client_dumpmessage(ns_client_t *client, const char *reason);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews ISC_LIST_APPEND(client->manager->recursing, client, link);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsns_client_killoldestquery(ns_client_t *client) {
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews oldest = ISC_LIST_HEAD(client->manager->recursing);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews ISC_LIST_APPEND(client->manager->active, oldest, link);
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrewsns_client_settimeout(ns_client_t *client, unsigned int seconds) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews result = isc_timer_reset(client->timer, isc_timertype_once, NULL,
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews "setting timeout: %s",
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews /* Continue anyway. */
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Check for a deactivation or shutdown request and take appropriate
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * action. Returns ISC_TRUE if either is in progress; in this case
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * the caller must no longer use the client object as it may have been
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews INSIST(client->newstate < NS_CLIENTSTATE_WORKING);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * We need to detach from the view early when shutting down
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * the server to break the following vicious circle:
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * - The resolver will not shut down until the view refcount is zero
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * - The view refcount does not go to zero until all clients detach
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * - The client does not detach from the view until references is zero
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * - references does not go to zero until the resolver has shut down
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Keep the view attached until any outstanding updates complete.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews client->newstate == NS_CLIENTSTATE_FREED && client->view != NULL)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews INSIST(client->newstate <= NS_CLIENTSTATE_READING);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Let the update processing complete.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * We are trying to abort request processing.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (! (client->nsends == 0 && client->nrecvs == 0 &&
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Still waiting for I/O cancel completion.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * or lingering references.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * I/O cancel is complete. Burn down all state
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * related to the current request. Ensure that
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * the client is on the active list and not the
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * recursing list.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (client->list == &client->manager->recursing) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews ISC_LIST_APPEND(client->manager->active, client, link);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (NS_CLIENTSTATE_READING == client->newstate) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * We are trying to abort the current TCP connection,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews INSIST(client->newstate <= NS_CLIENTSTATE_READY);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /* Still waiting for read cancel completion. */
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * Now the client is ready to accept a new TCP connection
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * or UDP request, but we may have enough clients doing
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * that already. Check whether this client needs to remain
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * active and force it to go inactive if not.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if (NS_CLIENTSTATE_READY == client->newstate) {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews INSIST(client->newstate <= NS_CLIENTSTATE_INACTIVE);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * We are trying to enter the inactive state.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_socket_cancel(client->tcplistener, client->task,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /* Still waiting for accept cancel completion. */
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /* Accept cancel is complete. */
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_socket_cancel(client->udpsocket, client->task,
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews /* Still waiting for recv cancel completion. */
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews /* Recv cancel is complete. */
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews /* Still waiting for control event to be delivered */
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews /* Deactivate the client. */
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Put the client on the inactive list. If we are aiming for
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * the "freed" state, it will be removed from the inactive
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * list shortly, and we need to keep the manager locked until
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * that has been done, lest the manager decide to reactivate
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * the dying client inbetween.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews ISC_LIST_APPEND(client->manager->inactive, client, link);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if (client->state == NS_CLIENTSTATE_INACTIVE) {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews INSIST(client->newstate == NS_CLIENTSTATE_FREED);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * We are trying to free the client.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * When "shuttingdown" is true, either the task has received
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * its shutdown event or no shutdown event has ever been
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * set up. Thus, we have no outstanding shutdown
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * event at this point.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews REQUIRE(client->state == NS_CLIENTSTATE_INACTIVE);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_event_free((isc_event_t **)&client->sendevent);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_event_free((isc_event_t **)&client->recvevent);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews INSIST(dns_rdataset_isassociated(client->opt));
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews dns_message_puttemprdataset(client->message, &client->opt);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * Detaching the task must be done after unlinking from
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * the manager's lists because the manager accesses
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * client->task.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * Check that there are no other external references to
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * the memory context.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews if (ns_g_clienttest && isc_mem_references(client->mctx) != 1) {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews isc_mem_putanddetach(&client->mctx, client, sizeof(*client));
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * Only now is it safe to destroy the client manager (if needed),
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * because we have accessed its lock for the last time.
b54630c4518a1a173fee3478f4bf51dff450b6dcMark Andrews * The client's task has received the client's control event
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * as part of the startup process.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrewsclient_start(isc_task_t *task, isc_event_t *event) {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews ns_client_t *client = (ns_client_t *) event->ev_arg;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * The client's task has received a shutdown event.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsclient_shutdown(isc_task_t *task, isc_event_t *event) {
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews REQUIRE(event->ev_type == ISC_TASKEVENT_SHUTDOWN);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews (client->shutdown)(client->shutdown_arg, ISC_R_SHUTTINGDOWN);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews INSIST(client->state == NS_CLIENTSTATE_WORKING);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews INSIST(dns_rdataset_isassociated(client->opt));
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews dns_message_puttemprdataset(client->message, &client->opt);
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * Clear all client attributes that are specific to
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * the request; that's all except the TCP flag.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * This client object should normally go inactive
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * at this point, but if we have fewer active client
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * objects than desired due to earlier quota exhaustion,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * keep it active to make up for the shortage.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * The UDP client quota is enforced by making
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * requests fail rather than by not listening
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * for new ones. Therefore, there is always a
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * full set of UDP clients listening.
34ee961fa2f0f5f2ee3cff40fdb4d7d7b48b7728Mark Andrews * We don't need this client object. Recycle it.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (client->newstate >= NS_CLIENTSTATE_INACTIVE)
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsns_client_next(ns_client_t *client, isc_result_t result) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews REQUIRE(client->state == NS_CLIENTSTATE_WORKING ||
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews "request failed: %s", isc_result_totext(result));
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * An error processing a TCP request may have left
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * the connection out of sync. To be safe, we always
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews * sever the connection when result != ISC_R_SUCCESS.
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews if (result == ISC_R_SUCCESS && TCP_CLIENT(client))
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrewsclient_senddone(isc_task_t *task, isc_event_t *event) {
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews isc_socketevent_t *sevent = (isc_socketevent_t *) event;
78da321b437bbb690ef570ccf17dcc8583a5a4a0Mark Andrews REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE);
static isc_result_t
unsigned char *data;
goto done;
goto done;
goto done;
done:
return (result);
static isc_result_t
isc_region_t r;
int match;
match > 0)
return (DNS_R_BLACKHOLED);
return (result);
unsigned char *data;
isc_region_t r;
goto done;
goto done;
goto done;
done:
unsigned char *data;
isc_region_t r;
unsigned int render_opts;
unsigned int preferred_glue;
render_opts = 0;
#ifdef ALLOW_FILTER_AAAA_ON_V4
preferred_glue = 0;
goto done;
goto done;
goto done;
goto done;
DNS_SECTION_QUESTION, 0);
goto renderend;
goto done;
goto renderend;
goto done;
goto renderend;
goto done;
goto done;
goto done;
if (cleanup_cctx) {
if (opt_included) {
done:
if (cleanup_cctx)
#define DROPPORT_NO 0
switch (port) {
return (DROPPORT_REQUEST);
return (DROPPORT_RESPONSE);
return (DROPPORT_NO);
DROPPORT_NO) {
isc_buffer_t b;
static inline isc_result_t
return (result);
return (result);
return (result);
goto no_nsid;
goto no_nsid;
== ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
static inline isc_boolean_t
int match;
return (ISC_TRUE);
return (ISC_TRUE);
return (ISC_FALSE);
return (ISC_FALSE);
if (!match)
int match;
unsigned int flags;
goto cleanup;
goto cleanup;
goto cleanup;
match > 0)
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
case dns_opcode_query:
case dns_opcode_update:
case dns_opcode_notify:
case dns_opcode_iquery:
goto cleanup;
goto cleanup;
goto cleanup;
&sockaddr);
goto cleanup;
view);
isc_buffer_t b;
isc_region_t *r;
sizeof(classname));
goto cleanup;
isc_buffer_t b;
goto cleanup;
case dns_opcode_query:
case dns_opcode_update:
case dns_opcode_notify:
case dns_opcode_iquery:
static isc_result_t
if (ns_g_clienttest) {
return (result);
#if NMCTXS > 0
return (result);
return (ISC_R_SUCCESS);
static isc_result_t
return (result);
return (ISC_R_NOMEMORY);
goto cleanup_client;
goto cleanup_task;
goto cleanup_timer;
sizeof(isc_socketevent_t));
goto cleanup_message;
goto cleanup_sendevent;
sizeof(isc_socketevent_t));
goto cleanup_recvbuf;
goto cleanup_recvevent;
goto cleanup_query;
return (ISC_R_SUCCESS);
return (result);
goto fail;
fail:
goto freeevent;
int match;
match > 0)
goto freeevent;
isc_region_t r;
return (result);
return (ISC_R_SUCCESS);
#if NMCTXS > 0
#if NMCTXS > 0
for (i = 0; i < NMCTXS; i++) {
#if NMCTXS > 0
return (ISC_R_NOMEMORY);
goto cleanup_manager;
#if NMCTXS > 0
for (i = 0; i < NMCTXS; i++)
return (ISC_R_SUCCESS);
return (result);
if (need_destroy)
REQUIRE(n > 0);
if (!ns_g_clienttest)
if (tcp) {
return (result);
int match;
if (default_allow)
goto allow;
goto deny;
if (match > 0)
goto allow;
return (ISC_R_SUCCESS);
deny:
return (DNS_R_REFUSED);
return (result);
classbuf);
0, &buffer);
buf);
const char *name;
const char *sep;
const char *origfor;
sizeof(original));
sizeof(typebuf));
sizeof(classbuf));