mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +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
|
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@
|
@BIND9_MAKE_RULES@
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ clientmgr_can_die(clientmgr_t *cm)
|
|||||||
if (ISC_LIST_HEAD(cm->running) != NULL)
|
if (ISC_LIST_HEAD(cm->running) != NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
lwres_context_destroy(&cm->lwctx);
|
||||||
dns_view_detach(&cm->view);
|
dns_view_detach(&cm->view);
|
||||||
isc_task_detach(&cm->task);
|
isc_task_detach(&cm->task);
|
||||||
}
|
}
|
||||||
@ -94,27 +95,30 @@ process_request(client_t *client)
|
|||||||
|
|
||||||
switch (pkt.opcode) {
|
switch (pkt.opcode) {
|
||||||
case LWRES_OPCODE_GETADDRSBYNAME:
|
case LWRES_OPCODE_GETADDRSBYNAME:
|
||||||
|
result = process_gabn(client, &b, &pkt);
|
||||||
break;
|
break;
|
||||||
case LWRES_OPCODE_GETNAMEBYADDR:
|
case LWRES_OPCODE_GETNAMEBYADDR:
|
||||||
|
result = process_gnba(client, &b, &pkt);
|
||||||
break;
|
break;
|
||||||
case LWRES_OPCODE_NOOP:
|
case LWRES_OPCODE_NOOP:
|
||||||
|
result = process_noop(client, &b, &pkt);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Unknown opcode %08x\n", pkt.opcode);
|
printf("Unknown opcode %08x\n", pkt.opcode);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
goto restart; /* XXXMLG temporary */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're working on something, so stay in the run queue.
|
* We're working on something, so stay in the run queue.
|
||||||
*/
|
*/
|
||||||
|
if (result == ISC_R_SUCCESS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
restart:
|
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_UNLINK(cm->running, client, link);
|
||||||
ISC_LIST_APPEND(cm->idle, client, link);
|
ISC_LIST_PREPEND(cm->idle, client, link);
|
||||||
client_start_recv(cm);
|
client_start_recv(cm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,6 +129,9 @@ client_recv(isc_task_t *task, isc_event_t *ev)
|
|||||||
clientmgr_t *cm = client->clientmgr;
|
clientmgr_t *cm = client->clientmgr;
|
||||||
isc_socketevent_t *dev = (isc_socketevent_t *)ev;
|
isc_socketevent_t *dev = (isc_socketevent_t *)ev;
|
||||||
|
|
||||||
|
INSIST(CLIENT_ISRECV(client));
|
||||||
|
CLIENT_SETRECVDONE(client);
|
||||||
|
|
||||||
INSIST((cm->flags & CLIENTMGR_FLAG_RECVPENDING) != 0);
|
INSIST((cm->flags & CLIENTMGR_FLAG_RECVPENDING) != 0);
|
||||||
cm->flags &= ~CLIENTMGR_FLAG_RECVPENDING;
|
cm->flags &= ~CLIENTMGR_FLAG_RECVPENDING;
|
||||||
|
|
||||||
@ -138,7 +145,7 @@ client_recv(isc_task_t *task, isc_event_t *ev)
|
|||||||
/*
|
/*
|
||||||
* Go idle.
|
* Go idle.
|
||||||
*/
|
*/
|
||||||
client->isidle = ISC_TRUE;
|
CLIENT_SETIDLE(client);
|
||||||
ISC_LIST_UNLINK(cm->running, client, link);
|
ISC_LIST_UNLINK(cm->running, client, link);
|
||||||
ISC_LIST_APPEND(cm->idle, 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);
|
client = ISC_LIST_HEAD(cm->idle);
|
||||||
if (client == NULL)
|
if (client == NULL)
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
INSIST(client->isidle);
|
INSIST(CLIENT_ISIDLE(client));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Issue the recv. If it fails, return that it did.
|
* 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
|
* Remove the client from the idle list, and put it on the running
|
||||||
* list.
|
* list.
|
||||||
*/
|
*/
|
||||||
client->isidle = ISC_FALSE;
|
CLIENT_SETRECV(client);
|
||||||
ISC_LIST_UNLINK(cm->idle, client, link);
|
ISC_LIST_UNLINK(cm->idle, client, link);
|
||||||
ISC_LIST_APPEND(cm->running, client, link);
|
ISC_LIST_APPEND(cm->running, client, link);
|
||||||
|
|
||||||
|
@ -45,17 +45,76 @@ struct client_s {
|
|||||||
unsigned char buffer[LWRES_RECVLENGTH]; /* receive buffer */
|
unsigned char buffer[LWRES_RECVLENGTH]; /* receive buffer */
|
||||||
isc_uint32_t length; /* length recv'd */
|
isc_uint32_t length; /* length recv'd */
|
||||||
|
|
||||||
isc_boolean_t isidle;
|
unsigned int state;
|
||||||
|
|
||||||
ISC_LINK(client_t) link;
|
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 {
|
struct clientmgr_s {
|
||||||
isc_task_t *task; /* owning task */
|
isc_task_t *task; /* owning task */
|
||||||
isc_socket_t *sock; /* socket to use */
|
isc_socket_t *sock; /* socket to use */
|
||||||
dns_view_t *view;
|
dns_view_t *view;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
isc_event_t sdev; /* shutdown event */
|
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) idle; /* idle client slots */
|
||||||
ISC_LIST(client_t) running; /* running clients */
|
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 *);
|
void client_shutdown(isc_task_t *, isc_event_t *);
|
||||||
isc_result_t client_start_recv(clientmgr_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 */
|
#endif /* LWD_CLIENT_H */
|
||||||
|
@ -188,6 +188,21 @@ out:
|
|||||||
return (result);
|
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
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -264,7 +279,7 @@ main(int argc, char **argv)
|
|||||||
for (i = 0 ; i < NTASKS ; i++) {
|
for (i = 0 ; i < NTASKS ; i++) {
|
||||||
cmgr[i].task = NULL;
|
cmgr[i].task = NULL;
|
||||||
cmgr[i].sock = sock;
|
cmgr[i].sock = sock;
|
||||||
dns_view_attach(view, &cmgr[i].view);
|
cmgr[i].view = NULL;
|
||||||
cmgr[i].flags = 0;
|
cmgr[i].flags = 0;
|
||||||
ISC_EVENT_INIT(&cmgr[i].sdev, sizeof(isc_event_t),
|
ISC_EVENT_INIT(&cmgr[i].sdev, sizeof(isc_event_t),
|
||||||
ISC_EVENTATTR_NOPURGE,
|
ISC_EVENTATTR_NOPURGE,
|
||||||
@ -274,7 +289,16 @@ main(int argc, char **argv)
|
|||||||
ISC_LIST_INIT(cmgr[i].idle);
|
ISC_LIST_INIT(cmgr[i].idle);
|
||||||
ISC_LIST_INIT(cmgr[i].running);
|
ISC_LIST_INIT(cmgr[i].running);
|
||||||
result = isc_task_create(taskmgr, mem, 0, &cmgr[i].task);
|
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);
|
INSIST(i > 0);
|
||||||
ntasks = i; /* remember how many we managed to create */
|
ntasks = i; /* remember how many we managed to create */
|
||||||
@ -293,7 +317,7 @@ main(int argc, char **argv)
|
|||||||
client[j].clientmgr = &cmgr[j];
|
client[j].clientmgr = &cmgr[j];
|
||||||
ISC_LINK_INIT(&client[j], link);
|
ISC_LINK_INIT(&client[j], link);
|
||||||
ISC_LIST_APPEND(cmgr[j].idle, &client[j], link);
|
ISC_LIST_APPEND(cmgr[j].idle, &client[j], link);
|
||||||
client[j].isidle = ISC_TRUE;
|
CLIENT_SETIDLE(&client[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
INSIST(i > 0);
|
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