mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
add client state bits, and start on individual parsing functions.
This commit is contained in:
parent
17614edd7e
commit
0061a9d4a3
@ -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);
|
||||
|
52
bin/lwresd/process.c
Normal file
52
bin/lwresd/process.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user