Commit 0061a9d4 authored by Michael Graff's avatar Michael Graff
Browse files

add client state bits, and start on individual parsing functions.

parent 17614edd
......@@ -36,9 +36,9 @@ LIBS = ${DEPLIBS} \
TARGETS = lwresd
OBJS = main.@O@ client.@O@
OBJS = main.@O@ client.@O@ process.@O@
SRCS = main.c client.c
SRCS = main.c client.c process.c
@BIND9_MAKE_RULES@
......
......@@ -67,6 +67,7 @@ clientmgr_can_die(clientmgr_t *cm)
if (ISC_LIST_HEAD(cm->running) != NULL)
return;
lwres_context_destroy(&cm->lwctx);
dns_view_detach(&cm->view);
isc_task_detach(&cm->task);
}
......@@ -94,27 +95,30 @@ process_request(client_t *client)
switch (pkt.opcode) {
case LWRES_OPCODE_GETADDRSBYNAME:
result = process_gabn(client, &b, &pkt);
break;
case LWRES_OPCODE_GETNAMEBYADDR:
result = process_gnba(client, &b, &pkt);
break;
case LWRES_OPCODE_NOOP:
result = process_noop(client, &b, &pkt);
break;
default:
printf("Unknown opcode %08x\n", pkt.opcode);
goto restart;
}
goto restart; /* XXXMLG temporary */
/*
* We're working on something, so stay in the run queue.
*/
return;
if (result == ISC_R_SUCCESS)
return;
restart:
client->isidle = ISC_TRUE;
printf("restarting client %p...\n", client);
client->state = CLIENT_STATE_IDLE;
ISC_LIST_UNLINK(cm->running, client, link);
ISC_LIST_APPEND(cm->idle, client, link);
ISC_LIST_PREPEND(cm->idle, client, link);
client_start_recv(cm);
}
......@@ -125,6 +129,9 @@ client_recv(isc_task_t *task, isc_event_t *ev)
clientmgr_t *cm = client->clientmgr;
isc_socketevent_t *dev = (isc_socketevent_t *)ev;
INSIST(CLIENT_ISRECV(client));
CLIENT_SETRECVDONE(client);
INSIST((cm->flags & CLIENTMGR_FLAG_RECVPENDING) != 0);
cm->flags &= ~CLIENTMGR_FLAG_RECVPENDING;
......@@ -138,7 +145,7 @@ client_recv(isc_task_t *task, isc_event_t *ev)
/*
* Go idle.
*/
client->isidle = ISC_TRUE;
CLIENT_SETIDLE(client);
ISC_LIST_UNLINK(cm->running, client, link);
ISC_LIST_APPEND(cm->idle, client, link);
......@@ -180,7 +187,7 @@ client_start_recv(clientmgr_t *cm)
client = ISC_LIST_HEAD(cm->idle);
if (client == NULL)
return (ISC_R_SUCCESS);
INSIST(client->isidle);
INSIST(CLIENT_ISIDLE(client));
/*
* Issue the recv. If it fails, return that it did.
......@@ -201,7 +208,7 @@ client_start_recv(clientmgr_t *cm)
* Remove the client from the idle list, and put it on the running
* list.
*/
client->isidle = ISC_FALSE;
CLIENT_SETRECV(client);
ISC_LIST_UNLINK(cm->idle, client, link);
ISC_LIST_APPEND(cm->running, client, link);
......
......@@ -45,17 +45,76 @@ struct client_s {
unsigned char buffer[LWRES_RECVLENGTH]; /* receive buffer */
isc_uint32_t length; /* length recv'd */
isc_boolean_t isidle;
unsigned int state;
ISC_LINK(client_t) link;
};
/*
* Client states.
*
* _IDLE The client is not doing anything at all.
*
* _RECV The client is waiting for data after issuing a socket recv().
*
* _RECVDONE Data has been received, and is being processed.
*
* _FINDWAIT An adb (or other) request was made that cannot be satisfied
* immediately. An event will wake the client up.
*
* _SEND All data for a response has completed, and a reply was
* sent via a socket send() call.
*
* _SENDDONE The send done event was received.
*
* Badly formatted state table:
*
* IDLE -> RECV when client has a recv() queued.
*
* RECV -> RECVDONE when recvdone event received.
*
* RECVDONE -> SEND if the data for a reply is at hand.
* RECVDONE -> FINDWAIT if more searching is needed, and events will
* eventually wake us up again.
*
* FINDWAIT -> SEND when enough data was received to reply.
*
* SENDDONE -> IDLE when a senddone event was received.
*
* At any time -> IDLE on error. Sometimes this will be -> SEND
* instead, if enough data is on hand to reply with a meaningful
* error.
*
* Packets which are badly formatted may or may not get error returns.
*/
#define CLIENT_STATE_IDLE 1
#define CLIENT_STATE_RECV 2
#define CLIENT_STATE_RECVDONE 3
#define CLIENT_STATE_FINDWAIT 4
#define CLIENT_STATE_SEND 5
#define CLIENT_STATE_SENDDONE 6
#define CLIENT_ISIDLE(c) ((c)->state == CLIENT_STATE_IDLE)
#define CLIENT_ISRECV(c) ((c)->state == CLIENT_STATE_RECV)
#define CLIENT_ISRECVDONE(c) ((c)->state == CLIENT_STATE_RECVDONE)
#define CLIENT_ISFINDWAIT(c) ((c)->state == CLIENT_STATE_FINDWAIT)
#define CLIENT_ISSEND(c) ((c)->state == CLIENT_STATE_SEND)
#define CLIENT_ISSENDDONE(c) ((c)->state == CLIENT_STATE_SENDDONE)
#define CLIENT_SETIDLE(c) ((c)->state = CLIENT_STATE_IDLE)
#define CLIENT_SETRECV(c) ((c)->state = CLIENT_STATE_RECV)
#define CLIENT_SETRECVDONE(c) ((c)->state = CLIENT_STATE_RECVDONE)
#define CLIENT_SETFINDWAIT(c) ((c)->state = CLIENT_STATE_FINDWAIT)
#define CLIENT_SETSEND(c) ((c)->state = CLIENT_STATE_SEND)
#define CLIENT_SETSENDDONE(c) ((c)->state = CLIENT_STATE_SENDDONE)
struct clientmgr_s {
isc_task_t *task; /* owning task */
isc_socket_t *sock; /* socket to use */
dns_view_t *view;
unsigned int flags;
isc_event_t sdev; /* shutdown event */
lwres_context_t *lwctx; /* lightweight proto context */
ISC_LIST(client_t) idle; /* idle client slots */
ISC_LIST(client_t) running; /* running clients */
};
......@@ -67,4 +126,11 @@ 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 *);
/*
* Processing functions of various types.
*/
isc_result_t process_gabn(client_t *, lwres_buffer_t *, lwres_lwpacket_t *);
isc_result_t process_gnba(client_t *, lwres_buffer_t *, lwres_lwpacket_t *);
isc_result_t process_noop(client_t *, lwres_buffer_t *, lwres_lwpacket_t *);
#endif /* LWD_CLIENT_H */
......@@ -188,6 +188,21 @@ out:
return (result);
}
/*
* Wrappers around our memory management stuff, for the lwres functions.
*/
static void *
mem_alloc(void *arg, size_t size)
{
return (isc_mem_get(arg, size));
}
static void
mem_free(void *arg, void *mem, size_t size)
{
isc_mem_put(arg, mem, size);
}
int
main(int argc, char **argv)
{
......@@ -264,7 +279,7 @@ main(int argc, char **argv)
for (i = 0 ; i < NTASKS ; i++) {
cmgr[i].task = NULL;
cmgr[i].sock = sock;
dns_view_attach(view, &cmgr[i].view);
cmgr[i].view = NULL;
cmgr[i].flags = 0;
ISC_EVENT_INIT(&cmgr[i].sdev, sizeof(isc_event_t),
ISC_EVENTATTR_NOPURGE,
......@@ -274,7 +289,16 @@ main(int argc, char **argv)
ISC_LIST_INIT(cmgr[i].idle);
ISC_LIST_INIT(cmgr[i].running);
result = isc_task_create(taskmgr, mem, 0, &cmgr[i].task);
INSIST(result == ISC_R_SUCCESS);
if (result != ISC_R_SUCCESS)
break;
cmgr[i].lwctx = NULL;
result = lwres_context_create(&cmgr[i].lwctx, mem,
mem_alloc, mem_free);
if (result != ISC_R_SUCCESS) {
isc_task_detach(&cmgr[i].task);
break;
}
dns_view_attach(view, &cmgr[i].view);
}
INSIST(i > 0);
ntasks = i; /* remember how many we managed to create */
......@@ -293,7 +317,7 @@ main(int argc, char **argv)
client[j].clientmgr = &cmgr[j];
ISC_LINK_INIT(&client[j], link);
ISC_LIST_APPEND(cmgr[j].idle, &client[j], link);
client[j].isidle = ISC_TRUE;
CLIENT_SETIDLE(&client[j]);
}
}
INSIST(i > 0);
......
/*
* 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 <config.h>
#include <sys/types.h>
#include <isc/assertions.h>
#include <isc/mem.h>
#include <isc/result.h>
#include <isc/sockaddr.h>
#include <isc/socket.h>
#include <isc/task.h>
#include <isc/util.h>
#include <lwres/lwres.h>
#include "client.h"
isc_result_t
process_gabn(client_t *client, lwres_buffer_t *b, lwres_lwpacket_t *pkt)
{
return (ISC_R_NOTIMPLEMENTED);
}
isc_result_t
process_gnba(client_t *client, lwres_buffer_t *b, lwres_lwpacket_t *pkt)
{
return (ISC_R_NOTIMPLEMENTED);
}
isc_result_t
process_noop(client_t *client, lwres_buffer_t *b, lwres_lwpacket_t *pkt)
{
lwres_lwpacket_t pkt;
return (ISC_R_NOTIMPLEMENTED);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment