Commit 9fc2037f authored by Brian Wellington's avatar Brian Wellington
Browse files

Remove bin/lwresd, as it's no longer used.

parent 21e82177
Makefile
.libs
*.la
*.lo
lwresd
# 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 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.
# $Id: Makefile.in,v 1.14 2001/01/09 21:39:29 bwelling Exp $
srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
@BIND9_VERSION@
@BIND9_INCLUDES@
CINCLUDES = ${LWRES_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES}
CDEFINES =
CWARNINGS =
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_OPENSSL_LIBS@ @DNS_GSSAPI_LIBS@
ISCLIBS = ../../lib/isc/libisc.@A@
LWRESLIBS = ../../lib/lwres/liblwres.@A@
DNSDEPLIBS = ../../lib/dns/libdns.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@
DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} ${LWRESDEPLIBS}
LIBS = ${DNSLIBS} ${ISCLIBS} ${LWRESLIBS} @LIBS@
TARGETS = lwresd
OBJS = main.@O@ client.@O@ err_pkt.@O@ \
process_gabn.@O@ process_gnba.@O@ process_noop.@O@
SRCS = main.c client.c err_pkt.c \
process_gabn.c process_gnba.c process_noop.c
@BIND9_MAKE_RULES@
lwresd: ${OBJS} ${UOBJS} ${DEPLIBS}
${LIBTOOL} ${CC} ${CFLAGS} -o $@ ${OBJS} ${UOBJS} ${LIBS}
clean distclean::
rm -f ${TARGETS}
/*
* 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 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.
*/
/* $Id: client.c,v 1.31 2001/01/09 21:39:30 bwelling Exp $ */
#include <config.h>
#include <isc/socket.h>
#include <isc/string.h>
#include <isc/task.h>
#include <isc/util.h>
#include <dns/view.h>
#include <dns/log.h>
#include "client.h"
void
DP(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);
}
void
hexdump(char *msg, void *base, size_t len) {
unsigned char *p;
unsigned int cnt;
char buffer[180];
char *n;
p = base;
cnt = 0;
n = buffer;
*n = 0;
printf("*** %s (%u bytes @ %p)\n", msg, len, base);
while (cnt < len) {
if (cnt % 16 == 0) {
n = buffer;
n += sprintf(buffer, "%p: ", p);
} else if (cnt % 8 == 0) {
*n++ = ' ';
*n++ = '|';
*n = 0;
}
n += sprintf(n, " %02x", *p++);
cnt++;
if (cnt % 16 == 0) {
DP(80, buffer);
n = buffer;
*n = 0;
}
}
if (n != buffer) {
DP(80, buffer);
n = buffer;
*n = 0;
}
}
static void
clientmgr_can_die(clientmgr_t *cm) {
if ((cm->flags & CLIENTMGR_FLAG_SHUTTINGDOWN) == 0)
return;
if (ISC_LIST_HEAD(cm->running) != NULL)
return;
lwres_context_destroy(&cm->lwctx);
dns_view_detach(&cm->view);
isc_task_detach(&cm->task);
}
static void
process_request(client_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) {
DP(50, "invalid packet header received");
goto restart;
}
DP(50, "opcode %08x", client->pkt.opcode);
switch (client->pkt.opcode) {
case LWRES_OPCODE_GETADDRSBYNAME:
process_gabn(client, &b);
return;
case LWRES_OPCODE_GETNAMEBYADDR:
process_gnba(client, &b);
return;
case LWRES_OPCODE_NOOP:
process_noop(client, &b);
return;
default:
DP(50, "unknown opcode %08x", client->pkt.opcode);
goto restart;
}
/*
* Drop the packet.
*/
restart:
DP(50, "restarting client %p...", client);
client_state_idle(client);
}
void
client_recv(isc_task_t *task, isc_event_t *ev) {
client_t *client = ev->ev_arg;
clientmgr_t *cm = client->clientmgr;
isc_socketevent_t *dev = (isc_socketevent_t *)ev;
INSIST(dev->region.base == client->buffer);
INSIST(CLIENT_ISRECV(client));
CLIENT_SETRECVDONE(client);
INSIST((cm->flags & CLIENTMGR_FLAG_RECVPENDING) != 0);
cm->flags &= ~CLIENTMGR_FLAG_RECVPENDING;
DP(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.
*/
client_state_idle(client);
return;
}
/*
* XXXMLG If we wanted to run on ipv6 as well, we'd need the pktinfo
* bits. Right now we don't, so don't remember them.
*/
client->recvlength = dev->n;
client->address = dev->address;
isc_event_free(&ev);
dev = NULL;
client_start_recv(cm);
process_request(client);
}
/*
* 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;
if ((cm->flags & CLIENTMGR_FLAG_SHUTTINGDOWN) != 0)
return (ISC_R_SUCCESS);
/*
* If a recv is already running, don't bother.
*/
if ((cm->flags & CLIENTMGR_FLAG_RECVPENDING) != 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(CLIENT_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, 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;
/*
* Remove the client from the idle list, and put it on the running
* list.
*/
CLIENT_SETRECV(client);
ISC_LIST_UNLINK(cm->idle, client, link);
ISC_LIST_APPEND(cm->running, client, link);
return (ISC_R_SUCCESS);
}
void
client_shutdown(isc_task_t *task, isc_event_t *ev) {
clientmgr_t *cm = ev->ev_arg;
REQUIRE(task == cm->task);
REQUIRE(ev->ev_type == LWRD_SHUTDOWN);
REQUIRE((cm->flags & CLIENTMGR_FLAG_SHUTTINGDOWN) == 0);
DP(50, "got shutdown event, task %p", 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;
}
/*
* Do all the crap needed to move a client from the run queue to the idle
* queue.
*/
void
client_state_idle(client_t *client) {
clientmgr_t *cm;
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);
CLIENT_SETIDLE(client);
clientmgr_can_die(cm);
client_start_recv(cm);
}
void
client_send(isc_task_t *task, isc_event_t *ev) {
client_t *client = ev->ev_arg;
clientmgr_t *cm = client->clientmgr;
isc_socketevent_t *dev = (isc_socketevent_t *)ev;
UNUSED(task);
UNUSED(dev);
INSIST(CLIENT_ISSEND(client));
INSIST(client->sendbuf == dev->region.base);
DP(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;
client_state_idle(client);
isc_event_free(&ev);
}
void
client_initialize(client_t *client, clientmgr_t *cmgr) {
client->clientmgr = cmgr;
ISC_LINK_INIT(client, link);
CLIENT_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->addrinfo = NULL;
ISC_LIST_APPEND(cmgr->idle, client, link);
}
void
client_init_aliases(client_t *client) {
int i;
for (i = 0 ; i < LWRES_MAX_ALIASES ; i++) {
client->aliases[i] = NULL;
client->aliaslen[i] = 0;
}
for (i = 0 ; i < LWRES_MAX_ADDRS ; i++) {
client->addrs[i].family = 0;
client->addrs[i].length = 0;
memset(client->addrs[i].address, 0, LWRES_ADDR_MAXLEN);
LWRES_LINK_INIT(&client->addrs[i], link);
}
}
void
client_init_gabn(client_t *client) {
/*
* Initialize the real name and alias arrays in the reply we're
* going to build up.
*/
client_init_aliases(client);
client->gabn.naliases = 0;
client->gabn.naddrs = 0;
client->gabn.realname = NULL;
client->gabn.aliases = client->aliases;
client->gabn.realnamelen = 0;
client->gabn.aliaslen = client->aliaslen;
LWRES_LIST_INIT(client->gabn.addrs);
client->gabn.base = NULL;
client->gabn.baselen = 0;
/*
* Set up the internal buffer to point to the receive region.
*/
isc_buffer_init(&client->recv_buffer, client->buffer,
LWRES_RECVLENGTH);
}
void
client_init_gnba(client_t *client) {
/*
* Initialize the real name and alias arrays in the reply we're
* going to build up.
*/
client_init_aliases(client);
client->gnba.naliases = 0;
client->gnba.realname = NULL;
client->gnba.aliases = client->aliases;
client->gnba.realnamelen = 0;
client->gnba.aliaslen = client->aliaslen;
client->gnba.base = NULL;
client->gnba.baselen = 0;
isc_buffer_init(&client->recv_buffer, client->buffer,
LWRES_RECVLENGTH);
}
/*
* 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 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.
*/
/* $Id: client.h,v 1.19 2001/01/09 21:39:31 bwelling Exp $ */
#ifndef LWD_CLIENT_H
#define LWD_CLIENT_H 1
#include <isc/event.h>
#include <isc/eventclass.h>
#include <isc/netaddr.h>
#include <isc/sockaddr.h>
#include <isc/types.h>
#include <dns/fixedname.h>
#include <dns/types.h>
#include <lwres/lwres.h>
#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_sockaddr_t address; /* where to reply */
clientmgr_t *clientmgr; /* our parent */
ISC_LINK(client_t) link;
unsigned int state;
void *arg; /* packet processing state */
/*
* Received data info.
*/
unsigned char buffer[LWRES_RECVLENGTH]; /* receive buffer */
isc_uint32_t recvlength; /* length recv'd */
lwres_lwpacket_t pkt;
/*
* Send data state. If sendbuf != buffer (that is, the send buffer
* isn't our receive buffer) it will be freed to the lwres_context_t.
*/
unsigned char *sendbuf;
isc_uint32_t sendlength;
isc_buffer_t recv_buffer;
/*
* gabn (get address by name) state info.
*/
dns_adbfind_t *find;
dns_adbfind_t *v4find;
dns_adbfind_t *v6find;
unsigned int find_wanted; /* Addresses we want */
dns_fixedname_t target_name;
lwres_gabnresponse_t gabn;
/*
* gnba (get name by address) state info.
*/
lwres_gnbaresponse_t gnba;
dns_byaddr_t *byaddr;
unsigned int options;
isc_netaddr_t na;
dns_adbaddrinfo_t *addrinfo;
/*
* Alias and address info. This is copied up to the gabn/gnba
* structures eventually.
*
* XXXMLG We can keep all of this in a client since we only service
* three packet types right now. If we started handling more,
* we'd need to use "arg" above and allocate/destroy things.
*/
char *aliases[LWRES_MAX_ALIASES];
isc_uint16_t aliaslen[LWRES_MAX_ALIASES];
lwres_addr_t addrs[LWRES_MAX_ADDRS];
};
/*
* 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.
*
* 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.
*
* SEND -> 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)
/*
* Overall magic test that means we're not idle.
*/
#define CLIENT_ISRUNNING(c) (!CLIENT_ISIDLE(c))
#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_mem_t *mctx;
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 */
};
#define CLIENTMGR_FLAG_RECVPENDING 0x00000001
#define CLIENTMGR_FLAG_SHUTTINGDOWN 0x00000002
void client_initialize(client_t *, clientmgr_t *);
isc_result_t client_start_recv(clientmgr_t *);
void client_state_idle(client_t *);
void client_recv(isc_task_t *, isc_event_t *);
void client_shutdown(isc_task_t *, isc_event_t *);
void client_send(isc_task_t *, isc_event_t *);
/*
* Processing functions of various types.
*/