client.c revision 915723e4007e177b10c0e1c9d1bfe77ac2bfe853
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein/*
297be3708069ef31814d6d75c0d71a50a78feb03Mark Andrews * Copyright (C) 2000 Internet Software Consortium.
75c0816e8295e180f4bc7f10db3d0d880383bc1cMark Andrews *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Permission to use, copy, modify, and distribute this software for any
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * purpose with or without fee is hereby granted, provided that the above
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * copyright notice and this permission notice appear in all copies.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * SOFTWARE.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <config.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <sys/types.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
e21a2904f02a03fa06b6db04d348f65fe9c67b2bMark Andrews#include <isc/assertions.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <isc/mem.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <isc/result.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <isc/sockaddr.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <isc/socket.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <isc/task.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <isc/util.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include <lwres/lwres.h>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein#include "client.h"
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinvoid
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob AusteinDP(int level, char *format, ...)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein{
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein va_list args;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein va_start(args, format);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein isc_log_vwrite(dns_lctx,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein ISC_LOG_DEBUG(level), format, args);
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater va_end(args);
297be3708069ef31814d6d75c0d71a50a78feb03Mark Andrews}
75c0816e8295e180f4bc7f10db3d0d880383bc1cMark Andrews
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinvoid
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinhexdump(char *msg, void *base, size_t len)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein{
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein unsigned char *p;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein unsigned int cnt;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein char buffer[180];
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein char *n;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater p = base;
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater cnt = 0;
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater n = buffer;
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater *n = 0;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater printf("*** %s (%u bytes @ %p)\n", msg, len, base);
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater while (cnt < len) {
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater if (cnt % 16 == 0) {
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater n = buffer;
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater n += sprintf(buffer, "%p: ", p);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein } else if (cnt % 8 == 0) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *n++ = ' ';
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews *n++ = '|';
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *n = 0;
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater }
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater n += sprintf(n, " %02x", *p++);
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater cnt++;
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater if (cnt % 16 == 0) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein DP(80, buffer);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein n = buffer;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *n = 0;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater if (n != buffer) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein DP(80, buffer);
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater n = buffer;
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater *n = 0;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater}
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinstatic void
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinclientmgr_can_die(clientmgr_t *cm)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein{
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if ((cm->flags & CLIENTMGR_FLAG_SHUTTINGDOWN) == 0)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if (ISC_LIST_HEAD(cm->running) != NULL)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return;
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater lwres_context_destroy(&cm->lwctx);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein dns_view_detach(&cm->view);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein isc_task_detach(&cm->task);
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater}
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updaterstatic void
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updaterprocess_request(client_t *client)
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater{
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater lwres_buffer_t b;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein isc_result_t result;
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater lwres_buffer_init(&b, client->buffer, client->recvlength);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein lwres_buffer_add(&b, client->recvlength);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
ab8729140b1ad688ab03e1e9ce438fb1cbb49222Automatic Updater result = lwres_lwpacket_parseheader(&b, &client->pkt);
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater if (result != ISC_R_SUCCESS) {
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater DP(50, "Invalid packet header received");
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein goto restart;
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater DP(50, "OPCODE %08x", client->pkt.opcode);
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein switch (client->pkt.opcode) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein case LWRES_OPCODE_GETADDRSBYNAME:
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews process_gabn(client, &b);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return;
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater case LWRES_OPCODE_GETNAMEBYADDR:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein process_gnba(client, &b);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return;
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews case LWRES_OPCODE_NOOP:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein process_noop(client, &b);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein default:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein DP(50, "Unknown opcode %08x", client->pkt.opcode);
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater goto restart;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /*
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater * Drop the packet.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein restart:
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater DP(50, "restarting client %p...", client);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein client_state_idle(client);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein}
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updatervoid
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinclient_recv(isc_task_t *task, isc_event_t *ev)
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater{
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater client_t *client = ev->arg;
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater clientmgr_t *cm = client->clientmgr;
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater isc_socketevent_t *dev = (isc_socketevent_t *)ev;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater INSIST(dev->region.base == client->buffer);
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater INSIST(CLIENT_ISRECV(client));
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater CLIENT_SETRECVDONE(client);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater INSIST((cm->flags & CLIENTMGR_FLAG_RECVPENDING) != 0);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein cm->flags &= ~CLIENTMGR_FLAG_RECVPENDING;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater DP(50, "Event received! Task %p, length %u, result %u (%s)",
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater task, dev->n, dev->result, isc_result_totext(dev->result));
c6d486af36165da7eb970354981d145249e342e4Mark Andrews
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if (dev->result != ISC_R_SUCCESS) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein isc_event_free(&ev);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein dev = NULL;
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater /*
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Go idle.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater client_state_idle(client);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return;
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater /*
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * XXXMLG If we wanted to run on ipv6 as well, we'd need the pktinfo
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * bits. Right now we don't, so don't remember them.
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein client->recvlength = dev->n;
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater client->address = dev->address;
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater isc_event_free(&ev);
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater dev = NULL;
7208386cd37a2092c70eddf80cf29519b16c4c80Mark Andrews
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein client_start_recv(cm);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews process_request(client);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein}
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater/*
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * This function will start a new recv() on a socket for this client manager.
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater */
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updaterisc_result_t
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinclient_start_recv(clientmgr_t *cm)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein{
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein client_t *client;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein isc_result_t result;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein isc_region_t r;
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater if ((cm->flags & CLIENTMGR_FLAG_SHUTTINGDOWN) != 0)
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater return (ISC_R_SUCCESS);
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /*
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * If a recv is already running, don't bother.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater if ((cm->flags & CLIENTMGR_FLAG_RECVPENDING) != 0)
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews return (ISC_R_SUCCESS);
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /*
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * If we have no idle slots, just return success.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein client = ISC_LIST_HEAD(cm->idle);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if (client == NULL)
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater return (ISC_R_SUCCESS);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein INSIST(CLIENT_ISIDLE(client));
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews /*
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * Issue the recv. If it fails, return that it did.
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews */
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews r.base = client->buffer;
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews r.length = LWRES_RECVLENGTH;
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews result = isc_socket_recv(cm->sock, &r, 0, cm->task, client_recv,
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews client);
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews if (result != ISC_R_SUCCESS)
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews return (result);
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater /*
28b3569d6248168e6c00caab951521cc8141a49dAutomatic Updater * Set the flag to say we've issued a recv() call.
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews */
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews cm->flags |= CLIENTMGR_FLAG_RECVPENDING;
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews /*
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * Remove the client from the idle list, and put it on the running
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews * list.
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews */
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews CLIENT_SETRECV(client);
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews ISC_LIST_UNLINK(cm->idle, client, link);
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews ISC_LIST_APPEND(cm->running, client, link);
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews return (ISC_R_SUCCESS);
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews}
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrewsvoid
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrewsclient_shutdown(isc_task_t *task, isc_event_t *ev)
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews{
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews clientmgr_t *cm = ev->arg;
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews REQUIRE(task == cm->task);
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews REQUIRE(ev->type == LWRD_SHUTDOWN);
71c66a876ecca77923638d3f94cc0783152b2f03Mark Andrews REQUIRE((cm->flags & CLIENTMGR_FLAG_SHUTTINGDOWN) == 0);
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews
5a4557e8de2951a2796676b5ec4b6a90caa5be14Mark Andrews DP(50, "Got shutdown event, task %p", task);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /*
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Cancel any pending I/O.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if ((cm->flags & CLIENTMGR_FLAG_RECVPENDING) != 0)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein isc_socket_cancel(cm->sock, task, ISC_SOCKCANCEL_ALL);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /*
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Run through the running client list and kill off any finds
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * in progress.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /* XXXMLG */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein cm->flags |= CLIENTMGR_FLAG_SHUTTINGDOWN;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein}
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein/*
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Do all the crap needed to move a client from the run queue to the idle
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * queue.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austeinvoid
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->arg;
clientmgr_t *cm = client->clientmgr;
isc_socketevent_t *dev = (isc_socketevent_t *)ev;
UNUSED(task);
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, ISC_BUFFERTYPE_TEXT);
}
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, ISC_BUFFERTYPE_TEXT);
}