diff options
Diffstat (limited to 'bin/named/include/named/lwdclient.h')
-rw-r--r-- | bin/named/include/named/lwdclient.h | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/bin/named/include/named/lwdclient.h b/bin/named/include/named/lwdclient.h new file mode 100644 index 0000000..65e630d --- /dev/null +++ b/bin/named/include/named/lwdclient.h @@ -0,0 +1,229 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* $Id: lwdclient.h,v 1.20 2009/01/17 23:47:42 tbox Exp $ */ + +#ifndef NAMED_LWDCLIENT_H +#define NAMED_LWDCLIENT_H 1 + +/*! \file */ + +#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> + +#include <named/lwsearch.h> + +#define LWRD_EVENTCLASS ISC_EVENTCLASS(4242) + +#define LWRD_SHUTDOWN (LWRD_EVENTCLASS + 0x0001) + +/*% Lightweight Resolver Daemon Client */ +struct ns_lwdclient { + isc_sockaddr_t address; /*%< where to reply */ + struct in6_pktinfo pktinfo; + bool pktinfo_valid; + ns_lwdclientmgr_t *clientmgr; /*%< our parent */ + ISC_LINK(ns_lwdclient_t) link; + unsigned int state; + void *arg; /*%< packet processing state */ + + /* + * Received data info. + */ + unsigned char buffer[LWRES_RECVLENGTH]; /*%< receive buffer */ + 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; + 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 query_name; + dns_fixedname_t target_name; + ns_lwsearchctx_t searchctx; + 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; + + /*% + * grbn (get rrset by name) state info. + * + * Note: this also uses target_name and searchctx. + */ + lwres_grbnresponse_t grbn; + dns_lookup_t *lookup; + dns_rdatatype_t rdtype; + + /*% + * 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]; + 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 NS_LWDCLIENT_STATEIDLE 1 +#define NS_LWDCLIENT_STATERECV 2 +#define NS_LWDCLIENT_STATERECVDONE 3 +#define NS_LWDCLIENT_STATEFINDWAIT 4 +#define NS_LWDCLIENT_STATESEND 5 +#define NS_LWDCLIENT_STATESENDDONE 6 + +#define NS_LWDCLIENT_ISIDLE(c) \ + ((c)->state == NS_LWDCLIENT_STATEIDLE) +#define NS_LWDCLIENT_ISRECV(c) \ + ((c)->state == NS_LWDCLIENT_STATERECV) +#define NS_LWDCLIENT_ISRECVDONE(c) \ + ((c)->state == NS_LWDCLIENT_STATERECVDONE) +#define NS_LWDCLIENT_ISFINDWAIT(c) \ + ((c)->state == NS_LWDCLIENT_STATEFINDWAIT) +#define NS_LWDCLIENT_ISSEND(c) \ + ((c)->state == NS_LWDCLIENT_STATESEND) + +/*% + * Overall magic test that means we're not idle. + */ +#define NS_LWDCLIENT_ISRUNNING(c) (!NS_LWDCLIENT_ISIDLE(c)) + +#define NS_LWDCLIENT_SETIDLE(c) \ + ((c)->state = NS_LWDCLIENT_STATEIDLE) +#define NS_LWDCLIENT_SETRECV(c) \ + ((c)->state = NS_LWDCLIENT_STATERECV) +#define NS_LWDCLIENT_SETRECVDONE(c) \ + ((c)->state = NS_LWDCLIENT_STATERECVDONE) +#define NS_LWDCLIENT_SETFINDWAIT(c) \ + ((c)->state = NS_LWDCLIENT_STATEFINDWAIT) +#define NS_LWDCLIENT_SETSEND(c) \ + ((c)->state = NS_LWDCLIENT_STATESEND) +#define NS_LWDCLIENT_SETSENDDONE(c) \ + ((c)->state = NS_LWDCLIENT_STATESENDDONE) + +/*% lightweight daemon client manager */ +struct ns_lwdclientmgr { + ns_lwreslistener_t *listener; + isc_mem_t *mctx; + isc_socket_t *sock; /*%< socket to use */ + dns_view_t *view; + lwres_context_t *lwctx; /*%< lightweight proto context */ + isc_task_t *task; /*%< owning task */ + unsigned int flags; + isc_mutex_t lock; + ISC_LINK(ns_lwdclientmgr_t) link; + ISC_LIST(ns_lwdclient_t) idle; /*%< idle client slots */ + ISC_LIST(ns_lwdclient_t) running; /*%< running clients */ +}; + +#define NS_LWDCLIENTMGR_FLAGRECVPENDING 0x00000001 +#define NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN 0x00000002 + +isc_result_t +ns_lwdclientmgr_create(ns_lwreslistener_t *, unsigned int, isc_taskmgr_t *); + +void +ns_lwdclient_initialize(ns_lwdclient_t *, ns_lwdclientmgr_t *); + +isc_result_t +ns_lwdclient_startrecv(ns_lwdclientmgr_t *); + +void +ns_lwdclient_stateidle(ns_lwdclient_t *); + +void +ns_lwdclient_recv(isc_task_t *, isc_event_t *); + +void +ns_lwdclient_shutdown(isc_task_t *, isc_event_t *); + +void +ns_lwdclient_send(isc_task_t *, isc_event_t *); + +isc_result_t +ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r); + +/* + * Processing functions of various types. + */ +void ns_lwdclient_processgabn(ns_lwdclient_t *, lwres_buffer_t *); +void ns_lwdclient_processgnba(ns_lwdclient_t *, lwres_buffer_t *); +void ns_lwdclient_processgrbn(ns_lwdclient_t *, lwres_buffer_t *); +void ns_lwdclient_processnoop(ns_lwdclient_t *, lwres_buffer_t *); + +void ns_lwdclient_errorpktsend(ns_lwdclient_t *, uint32_t); + +void ns_lwdclient_log(int level, const char *format, ...) + ISC_FORMAT_PRINTF(2, 3); + +#endif /* NAMED_LWDCLIENT_H */ |