diff options
Diffstat (limited to 'contrib/bind9/bin/named/lwdclient.c')
-rw-r--r-- | contrib/bind9/bin/named/lwdclient.c | 467 |
1 files changed, 0 insertions, 467 deletions
diff --git a/contrib/bind9/bin/named/lwdclient.c b/contrib/bind9/bin/named/lwdclient.c deleted file mode 100644 index 68069ed..0000000 --- a/contrib/bind9/bin/named/lwdclient.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000, 2001 Internet Software Consortium. - * - * 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. - * - * 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. - */ - -/* $Id: lwdclient.c,v 1.17.18.2 2005/04/29 00:15:23 marka Exp $ */ - -/*! \file */ - -#include <config.h> - -#include <isc/socket.h> -#include <isc/string.h> -#include <isc/task.h> -#include <isc/util.h> - -#include <dns/adb.h> -#include <dns/view.h> -#include <dns/log.h> - -#include <named/types.h> -#include <named/log.h> -#include <named/lwresd.h> -#include <named/lwdclient.h> - -#define SHUTTINGDOWN(cm) ((cm->flags & NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN) != 0) - -static void -lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev); - -void -ns_lwdclient_log(int level, const char *format, ...) { - va_list args; - - va_start(args, format); - isc_log_vwrite(dns_lctx, - DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB, - ISC_LOG_DEBUG(level), format, args); - va_end(args); -} - -isc_result_t -ns_lwdclientmgr_create(ns_lwreslistener_t *listener, unsigned int nclients, - isc_taskmgr_t *taskmgr) -{ - ns_lwresd_t *lwresd = listener->manager; - ns_lwdclientmgr_t *cm; - ns_lwdclient_t *client; - unsigned int i; - isc_result_t result = ISC_R_FAILURE; - - cm = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclientmgr_t)); - if (cm == NULL) - return (ISC_R_NOMEMORY); - - cm->listener = NULL; - ns_lwreslistener_attach(listener, &cm->listener); - cm->mctx = lwresd->mctx; - cm->sock = NULL; - isc_socket_attach(listener->sock, &cm->sock); - cm->view = lwresd->view; - cm->lwctx = NULL; - cm->task = NULL; - cm->flags = 0; - ISC_LINK_INIT(cm, link); - ISC_LIST_INIT(cm->idle); - ISC_LIST_INIT(cm->running); - - if (lwres_context_create(&cm->lwctx, cm->mctx, - ns__lwresd_memalloc, ns__lwresd_memfree, - LWRES_CONTEXT_SERVERMODE) - != ISC_R_SUCCESS) - goto errout; - - for (i = 0; i < nclients; i++) { - client = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclient_t)); - if (client != NULL) { - ns_lwdclient_log(50, "created client %p, manager %p", - client, cm); - ns_lwdclient_initialize(client, cm); - } - } - - /* - * If we could create no clients, clean up and return. - */ - if (ISC_LIST_EMPTY(cm->idle)) - goto errout; - - result = isc_task_create(taskmgr, 0, &cm->task); - if (result != ISC_R_SUCCESS) - goto errout; - - /* - * This MUST be last, since there is no way to cancel an onshutdown... - */ - result = isc_task_onshutdown(cm->task, lwdclientmgr_shutdown_callback, - cm); - if (result != ISC_R_SUCCESS) - goto errout; - - ns_lwreslistener_linkcm(listener, cm); - - return (ISC_R_SUCCESS); - - errout: - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(lwresd->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - if (cm->task != NULL) - isc_task_detach(&cm->task); - - if (cm->lwctx != NULL) - lwres_context_destroy(&cm->lwctx); - - isc_mem_put(lwresd->mctx, cm, sizeof(*cm)); - return (result); -} - -static void -lwdclientmgr_destroy(ns_lwdclientmgr_t *cm) { - ns_lwdclient_t *client; - ns_lwreslistener_t *listener; - - if (!SHUTTINGDOWN(cm)) - return; - - /* - * run through the idle list and free the clients there. Idle - * clients do not have a recv running nor do they have any finds - * or similar running. - */ - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ns_lwdclient_log(50, "destroying client %p, manager %p", - client, cm); - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(cm->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - if (!ISC_LIST_EMPTY(cm->running)) - return; - - lwres_context_destroy(&cm->lwctx); - cm->view = NULL; - isc_socket_detach(&cm->sock); - isc_task_detach(&cm->task); - - listener = cm->listener; - ns_lwreslistener_unlinkcm(listener, cm); - ns_lwdclient_log(50, "destroying manager %p", cm); - isc_mem_put(cm->mctx, cm, sizeof(*cm)); - ns_lwreslistener_detach(&listener); -} - -static void -process_request(ns_lwdclient_t *client) { - lwres_buffer_t b; - isc_result_t result; - - lwres_buffer_init(&b, client->buffer, client->recvlength); - lwres_buffer_add(&b, client->recvlength); - - result = lwres_lwpacket_parseheader(&b, &client->pkt); - if (result != ISC_R_SUCCESS) { - ns_lwdclient_log(50, "invalid packet header received"); - goto restart; - } - - ns_lwdclient_log(50, "opcode %08x", client->pkt.opcode); - - switch (client->pkt.opcode) { - case LWRES_OPCODE_GETADDRSBYNAME: - ns_lwdclient_processgabn(client, &b); - return; - case LWRES_OPCODE_GETNAMEBYADDR: - ns_lwdclient_processgnba(client, &b); - return; - case LWRES_OPCODE_GETRDATABYNAME: - ns_lwdclient_processgrbn(client, &b); - return; - case LWRES_OPCODE_NOOP: - ns_lwdclient_processnoop(client, &b); - return; - default: - ns_lwdclient_log(50, "unknown opcode %08x", client->pkt.opcode); - goto restart; - } - - /* - * Drop the packet. - */ - restart: - ns_lwdclient_log(50, "restarting client %p...", client); - ns_lwdclient_stateidle(client); -} - -void -ns_lwdclient_recv(isc_task_t *task, isc_event_t *ev) { - isc_result_t result; - ns_lwdclient_t *client = ev->ev_arg; - ns_lwdclientmgr_t *cm = client->clientmgr; - isc_socketevent_t *dev = (isc_socketevent_t *)ev; - - INSIST(dev->region.base == client->buffer); - INSIST(NS_LWDCLIENT_ISRECV(client)); - - NS_LWDCLIENT_SETRECVDONE(client); - - INSIST((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0); - cm->flags &= ~NS_LWDCLIENTMGR_FLAGRECVPENDING; - - ns_lwdclient_log(50, - "event received: task %p, length %u, result %u (%s)", - task, dev->n, dev->result, - isc_result_totext(dev->result)); - - if (dev->result != ISC_R_SUCCESS) { - isc_event_free(&ev); - dev = NULL; - - /* - * Go idle. - */ - ns_lwdclient_stateidle(client); - - return; - } - - client->recvlength = dev->n; - client->address = dev->address; - if ((dev->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { - client->pktinfo = dev->pktinfo; - client->pktinfo_valid = ISC_TRUE; - } else - client->pktinfo_valid = ISC_FALSE; - isc_event_free(&ev); - dev = NULL; - - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); - - process_request(client); -} - -/* - * This function will start a new recv() on a socket for this client manager. - */ -isc_result_t -ns_lwdclient_startrecv(ns_lwdclientmgr_t *cm) { - ns_lwdclient_t *client; - isc_result_t result; - isc_region_t r; - - if (SHUTTINGDOWN(cm)) { - lwdclientmgr_destroy(cm); - return (ISC_R_SUCCESS); - } - - /* - * If a recv is already running, don't bother. - */ - if ((cm->flags & NS_LWDCLIENTMGR_FLAGRECVPENDING) != 0) - return (ISC_R_SUCCESS); - - /* - * If we have no idle slots, just return success. - */ - client = ISC_LIST_HEAD(cm->idle); - if (client == NULL) - return (ISC_R_SUCCESS); - INSIST(NS_LWDCLIENT_ISIDLE(client)); - - /* - * Issue the recv. If it fails, return that it did. - */ - r.base = client->buffer; - r.length = LWRES_RECVLENGTH; - result = isc_socket_recv(cm->sock, &r, 0, cm->task, ns_lwdclient_recv, - client); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Set the flag to say we've issued a recv() call. - */ - cm->flags |= NS_LWDCLIENTMGR_FLAGRECVPENDING; - - /* - * Remove the client from the idle list, and put it on the running - * list. - */ - NS_LWDCLIENT_SETRECV(client); - ISC_LIST_UNLINK(cm->idle, client, link); - ISC_LIST_APPEND(cm->running, client, link); - - return (ISC_R_SUCCESS); -} - -static void -lwdclientmgr_shutdown_callback(isc_task_t *task, isc_event_t *ev) { - ns_lwdclientmgr_t *cm = ev->ev_arg; - ns_lwdclient_t *client; - - REQUIRE(!SHUTTINGDOWN(cm)); - - ns_lwdclient_log(50, "got shutdown event, task %p, lwdclientmgr %p", - task, cm); - - /* - * run through the idle list and free the clients there. Idle - * clients do not have a recv running nor do they have any finds - * or similar running. - */ - client = ISC_LIST_HEAD(cm->idle); - while (client != NULL) { - ns_lwdclient_log(50, "destroying client %p, manager %p", - client, cm); - ISC_LIST_UNLINK(cm->idle, client, link); - isc_mem_put(cm->mctx, client, sizeof(*client)); - client = ISC_LIST_HEAD(cm->idle); - } - - /* - * Cancel any pending I/O. - */ - isc_socket_cancel(cm->sock, task, ISC_SOCKCANCEL_ALL); - - /* - * Run through the running client list and kill off any finds - * in progress. - */ - client = ISC_LIST_HEAD(cm->running); - while (client != NULL) { - if (client->find != client->v4find - && client->find != client->v6find) - dns_adb_cancelfind(client->find); - if (client->v4find != NULL) - dns_adb_cancelfind(client->v4find); - if (client->v6find != NULL) - dns_adb_cancelfind(client->v6find); - client = ISC_LIST_NEXT(client, link); - } - - cm->flags |= NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN; - - isc_event_free(&ev); -} - -/* - * Do all the crap needed to move a client from the run queue to the idle - * queue. - */ -void -ns_lwdclient_stateidle(ns_lwdclient_t *client) { - ns_lwdclientmgr_t *cm; - isc_result_t result; - - cm = client->clientmgr; - - INSIST(client->sendbuf == NULL); - INSIST(client->sendlength == 0); - INSIST(client->arg == NULL); - INSIST(client->v4find == NULL); - INSIST(client->v6find == NULL); - - ISC_LIST_UNLINK(cm->running, client, link); - ISC_LIST_PREPEND(cm->idle, client, link); - - NS_LWDCLIENT_SETIDLE(client); - - result = ns_lwdclient_startrecv(cm); - if (result != ISC_R_SUCCESS) - isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, - NS_LOGMODULE_LWRESD, ISC_LOG_ERROR, - "could not start lwres " - "client handler: %s", - isc_result_totext(result)); -} - -void -ns_lwdclient_send(isc_task_t *task, isc_event_t *ev) { - ns_lwdclient_t *client = ev->ev_arg; - ns_lwdclientmgr_t *cm = client->clientmgr; - isc_socketevent_t *dev = (isc_socketevent_t *)ev; - - UNUSED(task); - UNUSED(dev); - - INSIST(NS_LWDCLIENT_ISSEND(client)); - INSIST(client->sendbuf == dev->region.base); - - ns_lwdclient_log(50, "task %p for client %p got send-done event", - task, client); - - if (client->sendbuf != client->buffer) - lwres_context_freemem(cm->lwctx, client->sendbuf, - client->sendlength); - client->sendbuf = NULL; - client->sendlength = 0; - - ns_lwdclient_stateidle(client); - - isc_event_free(&ev); -} - -isc_result_t -ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r) { - struct in6_pktinfo *pktinfo; - ns_lwdclientmgr_t *cm = client->clientmgr; - - if (client->pktinfo_valid) - pktinfo = &client->pktinfo; - else - pktinfo = NULL; - return (isc_socket_sendto(cm->sock, r, cm->task, ns_lwdclient_send, - client, &client->address, pktinfo)); -} - -void -ns_lwdclient_initialize(ns_lwdclient_t *client, ns_lwdclientmgr_t *cmgr) { - client->clientmgr = cmgr; - ISC_LINK_INIT(client, link); - NS_LWDCLIENT_SETIDLE(client); - client->arg = NULL; - - client->recvlength = 0; - - client->sendbuf = NULL; - client->sendlength = 0; - - client->find = NULL; - client->v4find = NULL; - client->v6find = NULL; - client->find_wanted = 0; - - client->options = 0; - client->byaddr = NULL; - - client->lookup = NULL; - - client->pktinfo_valid = ISC_FALSE; - - ISC_LIST_APPEND(cmgr->idle, client, link); -} |