From dd5f72cc1c20cdfcf3cc86ca92b4084a02f1db0a Mon Sep 17 00:00:00 2001 From: Michael Graff Date: Thu, 20 Jan 2000 00:05:11 +0000 Subject: [PATCH] checkpoint --- bin/lwresd/Makefile.in | 4 +- bin/lwresd/client.c | 132 +++++++++++++++++++++++++++++++++++++++++ bin/lwresd/client.h | 21 ++++++- 3 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 bin/lwresd/client.c diff --git a/bin/lwresd/Makefile.in b/bin/lwresd/Makefile.in index 63494e1f45..a105cf5f79 100644 --- a/bin/lwresd/Makefile.in +++ b/bin/lwresd/Makefile.in @@ -36,9 +36,9 @@ LIBS = ${DEPLIBS} \ TARGETS = lwresd -OBJS = main.@O@ +OBJS = main.@O@ client.@O@ -SRCS = main.c +SRCS = main.c client.c @BIND9_MAKE_RULES@ diff --git a/bin/lwresd/client.c b/bin/lwresd/client.c new file mode 100644 index 0000000000..5221b25f4d --- /dev/null +++ b/bin/lwresd/client.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 1999 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM 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. + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "client.h" + +static void +clientmgr_can_die(clientmgr_t *cm) +{ + if (ISC_LIST_HEAD(cm->running) != NULL) + return; + + isc_task_detach(&cm->task); +} + +void +client_recv(isc_task_t *task, isc_event_t *ev) +{ + client_t *client = ev->arg; + clientmgr_t *cm = client->clientmgr; + isc_socketevent_t *dev = (isc_socketevent_t *)ev; + + INSIST((cm->flags & CLIENTMGR_FLAG_RECVPENDING) != 0); + cm->flags &= ~CLIENTMGR_FLAG_RECVPENDING; + + printf("Event received! Task %p, length %u, result %u (%s)\n", + task, dev->n, dev->result, isc_result_totext(dev->result)); + + if (dev->result != ISC_R_SUCCESS) { + isc_event_free(&ev); + dev = NULL; + + clientmgr_can_die(cm); + return; + } + + client_start_recv(cm); + + isc_event_free(&ev); +} + +/* + * This function will start a new recv() on a socket for this client manager. + */ +isc_result_t +client_start_recv(clientmgr_t *cm) +{ + client_t *client; + isc_result_t result; + isc_region_t r; + + REQUIRE((cm->flags & CLIENTMGR_FLAG_SHUTTINGDOWN) == 0); + REQUIRE((cm->flags & CLIENTMGR_FLAG_RECVPENDING) == 0); + + /* + * If we have no idle slots, just return success. + */ + client = ISC_LIST_HEAD(cm->idle); + if (client == NULL) + return (ISC_R_SUCCESS); + + /* + * 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, client_recv, + client); + if (result != ISC_R_SUCCESS) + return (result); + + /* + * Set the flag to say we've issued a recv() call. + */ + cm->flags |= CLIENTMGR_FLAG_RECVPENDING; + + return (ISC_R_SUCCESS); +} + +void +client_shutdown(isc_task_t *task, isc_event_t *ev) +{ + clientmgr_t *cm = ev->arg; + + REQUIRE(task == cm->task); + REQUIRE(ev->type == LWRD_SHUTDOWN); + REQUIRE((cm->flags & CLIENTMGR_FLAG_SHUTTINGDOWN) == 0); + + printf("Got shutdown event, task %p\n", task); + + /* + * Cancel any pending I/O. + */ + if ((cm->flags & CLIENTMGR_FLAG_RECVPENDING) != 0) + isc_socket_cancel(cm->sock, task, ISC_SOCKCANCEL_ALL); + + /* + * Run through the running client list and kill off any finds + * in progress. + */ + /* XXXMLG */ + + cm->flags |= CLIENTMGR_FLAG_SHUTTINGDOWN; +} + diff --git a/bin/lwresd/client.h b/bin/lwresd/client.h index 8a0a0363fc..a7566b31ed 100644 --- a/bin/lwresd/client.h +++ b/bin/lwresd/client.h @@ -18,26 +18,43 @@ #ifndef LWD_CLIENT_H #define LWD_CLIENT_H 1 +#include +#include #include #include #include #include #include +#define LWRD_EVENTCLASS ISC_EVENTCLASS(4242) + +#define LWRD_SHUTDOWN (LWRD_EVENTCLASS + 0x0001) + typedef struct client_s client_t; +typedef struct clientmgr_s clientmgr_t; + struct client_s { - isc_socket_t *socket; /* socket to reply */ isc_sockaddr_t sockaddr; /* where to reply */ + clientmgr_t *clientmgr; /* our parent */ unsigned char buffer[LWRES_RECVLENGTH]; /* receive buffer */ ISC_LINK(client_t) link; }; -typedef struct clientmgr_s clientmgr_t; struct clientmgr_s { isc_task_t *task; /* owning task */ + isc_socket_t *sock; /* socket to use */ + unsigned int flags; + isc_event_t sdev; /* shutdown event */ ISC_LIST(client_t) idle; /* idle client slots */ ISC_LIST(client_t) running; /* running clients */ }; +#define CLIENTMGR_FLAG_RECVPENDING 0x00000001 +#define CLIENTMGR_FLAG_SHUTTINGDOWN 0x00000002 + +void client_recv(isc_task_t *, isc_event_t *); +void client_shutdown(isc_task_t *, isc_event_t *); +isc_result_t client_start_recv(clientmgr_t *); + #endif /* LWD_CLIENT_H */