1135446Strhodes/*
2193149Sdougb * Copyright (C) 2004, 2005, 2007, 2009  Internet Systems Consortium, Inc. ("ISC")
3135446Strhodes * Copyright (C) 2000, 2001  Internet Software Consortium.
4135446Strhodes *
5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any
6135446Strhodes * purpose with or without fee is hereby granted, provided that the above
7135446Strhodes * copyright notice and this permission notice appear in all copies.
8135446Strhodes *
9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11135446Strhodes * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15135446Strhodes * PERFORMANCE OF THIS SOFTWARE.
16135446Strhodes */
17135446Strhodes
18234010Sdougb/* $Id: lwdclient.h,v 1.20 2009/01/17 23:47:42 tbox Exp $ */
19135446Strhodes
20135446Strhodes#ifndef NAMED_LWDCLIENT_H
21135446Strhodes#define NAMED_LWDCLIENT_H 1
22135446Strhodes
23170222Sdougb/*! \file */
24170222Sdougb
25135446Strhodes#include <isc/event.h>
26135446Strhodes#include <isc/eventclass.h>
27135446Strhodes#include <isc/netaddr.h>
28135446Strhodes#include <isc/sockaddr.h>
29135446Strhodes#include <isc/types.h>
30135446Strhodes
31135446Strhodes#include <dns/fixedname.h>
32135446Strhodes#include <dns/types.h>
33135446Strhodes
34135446Strhodes#include <lwres/lwres.h>
35135446Strhodes
36135446Strhodes#include <named/lwsearch.h>
37135446Strhodes
38135446Strhodes#define LWRD_EVENTCLASS		ISC_EVENTCLASS(4242)
39135446Strhodes
40135446Strhodes#define LWRD_SHUTDOWN		(LWRD_EVENTCLASS + 0x0001)
41135446Strhodes
42193149Sdougb/*% Lightweight Resolver Daemon Client */
43135446Strhodesstruct ns_lwdclient {
44170222Sdougb	isc_sockaddr_t		address;	/*%< where to reply */
45135446Strhodes	struct in6_pktinfo	pktinfo;
46135446Strhodes	isc_boolean_t		pktinfo_valid;
47170222Sdougb	ns_lwdclientmgr_t	*clientmgr;	/*%< our parent */
48135446Strhodes	ISC_LINK(ns_lwdclient_t) link;
49135446Strhodes	unsigned int		state;
50170222Sdougb	void			*arg;		/*%< packet processing state */
51135446Strhodes
52135446Strhodes	/*
53135446Strhodes	 * Received data info.
54135446Strhodes	 */
55170222Sdougb	unsigned char		buffer[LWRES_RECVLENGTH]; /*%< receive buffer */
56170222Sdougb	isc_uint32_t		recvlength;	/*%< length recv'd */
57135446Strhodes	lwres_lwpacket_t	pkt;
58135446Strhodes
59170222Sdougb	/*%
60135446Strhodes	 * Send data state.  If sendbuf != buffer (that is, the send buffer
61135446Strhodes	 * isn't our receive buffer) it will be freed to the lwres_context_t.
62135446Strhodes	 */
63135446Strhodes	unsigned char	       *sendbuf;
64135446Strhodes	isc_uint32_t		sendlength;
65135446Strhodes	isc_buffer_t		recv_buffer;
66135446Strhodes
67170222Sdougb	/*%
68135446Strhodes	 * gabn (get address by name) state info.
69135446Strhodes	 */
70135446Strhodes	dns_adbfind_t		*find;
71135446Strhodes	dns_adbfind_t		*v4find;
72135446Strhodes	dns_adbfind_t		*v6find;
73170222Sdougb	unsigned int		find_wanted;	/*%< Addresses we want */
74135446Strhodes	dns_fixedname_t		query_name;
75135446Strhodes	dns_fixedname_t		target_name;
76135446Strhodes	ns_lwsearchctx_t	searchctx;
77135446Strhodes	lwres_gabnresponse_t	gabn;
78135446Strhodes
79170222Sdougb	/*%
80135446Strhodes	 * gnba (get name by address) state info.
81135446Strhodes	 */
82135446Strhodes	lwres_gnbaresponse_t	gnba;
83135446Strhodes	dns_byaddr_t	       *byaddr;
84135446Strhodes	unsigned int		options;
85135446Strhodes	isc_netaddr_t		na;
86135446Strhodes
87170222Sdougb	/*%
88135446Strhodes	 * grbn (get rrset by name) state info.
89135446Strhodes	 *
90135446Strhodes	 * Note: this also uses target_name and searchctx.
91135446Strhodes	 */
92135446Strhodes	lwres_grbnresponse_t	grbn;
93135446Strhodes	dns_lookup_t	       *lookup;
94135446Strhodes	dns_rdatatype_t		rdtype;
95135446Strhodes
96170222Sdougb	/*%
97135446Strhodes	 * Alias and address info.  This is copied up to the gabn/gnba
98135446Strhodes	 * structures eventually.
99135446Strhodes	 *
100135446Strhodes	 * XXXMLG We can keep all of this in a client since we only service
101135446Strhodes	 * three packet types right now.  If we started handling more,
102135446Strhodes	 * we'd need to use "arg" above and allocate/destroy things.
103135446Strhodes	 */
104135446Strhodes	char		       *aliases[LWRES_MAX_ALIASES];
105135446Strhodes	isc_uint16_t		aliaslen[LWRES_MAX_ALIASES];
106135446Strhodes	lwres_addr_t		addrs[LWRES_MAX_ADDRS];
107135446Strhodes};
108135446Strhodes
109170222Sdougb/*%
110135446Strhodes * Client states.
111135446Strhodes *
112135446Strhodes * _IDLE	The client is not doing anything at all.
113135446Strhodes *
114135446Strhodes * _RECV	The client is waiting for data after issuing a socket recv().
115135446Strhodes *
116135446Strhodes * _RECVDONE	Data has been received, and is being processed.
117135446Strhodes *
118135446Strhodes * _FINDWAIT	An adb (or other) request was made that cannot be satisfied
119135446Strhodes *		immediately.  An event will wake the client up.
120135446Strhodes *
121135446Strhodes * _SEND	All data for a response has completed, and a reply was
122135446Strhodes *		sent via a socket send() call.
123135446Strhodes *
124135446Strhodes * Badly formatted state table:
125135446Strhodes *
126135446Strhodes *	IDLE -> RECV when client has a recv() queued.
127135446Strhodes *
128135446Strhodes *	RECV -> RECVDONE when recvdone event received.
129135446Strhodes *
130135446Strhodes *	RECVDONE -> SEND if the data for a reply is at hand.
131135446Strhodes *	RECVDONE -> FINDWAIT if more searching is needed, and events will
132135446Strhodes *		eventually wake us up again.
133135446Strhodes *
134135446Strhodes *	FINDWAIT -> SEND when enough data was received to reply.
135135446Strhodes *
136135446Strhodes *	SEND -> IDLE when a senddone event was received.
137135446Strhodes *
138135446Strhodes *	At any time -> IDLE on error.  Sometimes this will be -> SEND
139135446Strhodes *	instead, if enough data is on hand to reply with a meaningful
140135446Strhodes *	error.
141135446Strhodes *
142135446Strhodes *	Packets which are badly formatted may or may not get error returns.
143135446Strhodes */
144135446Strhodes#define NS_LWDCLIENT_STATEIDLE		1
145135446Strhodes#define NS_LWDCLIENT_STATERECV		2
146135446Strhodes#define NS_LWDCLIENT_STATERECVDONE	3
147135446Strhodes#define NS_LWDCLIENT_STATEFINDWAIT	4
148135446Strhodes#define NS_LWDCLIENT_STATESEND		5
149135446Strhodes#define NS_LWDCLIENT_STATESENDDONE	6
150135446Strhodes
151135446Strhodes#define NS_LWDCLIENT_ISIDLE(c)		\
152135446Strhodes			((c)->state == NS_LWDCLIENT_STATEIDLE)
153135446Strhodes#define NS_LWDCLIENT_ISRECV(c)		\
154135446Strhodes			((c)->state == NS_LWDCLIENT_STATERECV)
155135446Strhodes#define NS_LWDCLIENT_ISRECVDONE(c)	\
156135446Strhodes			((c)->state == NS_LWDCLIENT_STATERECVDONE)
157135446Strhodes#define NS_LWDCLIENT_ISFINDWAIT(c)	\
158135446Strhodes			((c)->state == NS_LWDCLIENT_STATEFINDWAIT)
159135446Strhodes#define NS_LWDCLIENT_ISSEND(c)		\
160135446Strhodes			((c)->state == NS_LWDCLIENT_STATESEND)
161135446Strhodes
162170222Sdougb/*%
163135446Strhodes * Overall magic test that means we're not idle.
164135446Strhodes */
165135446Strhodes#define NS_LWDCLIENT_ISRUNNING(c)	(!NS_LWDCLIENT_ISIDLE(c))
166135446Strhodes
167135446Strhodes#define NS_LWDCLIENT_SETIDLE(c)		\
168135446Strhodes			((c)->state = NS_LWDCLIENT_STATEIDLE)
169135446Strhodes#define NS_LWDCLIENT_SETRECV(c)		\
170135446Strhodes			((c)->state = NS_LWDCLIENT_STATERECV)
171135446Strhodes#define NS_LWDCLIENT_SETRECVDONE(c)	\
172135446Strhodes			((c)->state = NS_LWDCLIENT_STATERECVDONE)
173135446Strhodes#define NS_LWDCLIENT_SETFINDWAIT(c)	\
174135446Strhodes			((c)->state = NS_LWDCLIENT_STATEFINDWAIT)
175135446Strhodes#define NS_LWDCLIENT_SETSEND(c)		\
176135446Strhodes			((c)->state = NS_LWDCLIENT_STATESEND)
177135446Strhodes#define NS_LWDCLIENT_SETSENDDONE(c)	\
178135446Strhodes			((c)->state = NS_LWDCLIENT_STATESENDDONE)
179135446Strhodes
180170222Sdougb/*% lightweight daemon client manager */
181135446Strhodesstruct ns_lwdclientmgr {
182135446Strhodes	ns_lwreslistener_t     *listener;
183135446Strhodes	isc_mem_t	       *mctx;
184170222Sdougb	isc_socket_t	       *sock;		/*%< socket to use */
185135446Strhodes	dns_view_t	       *view;
186170222Sdougb	lwres_context_t	       *lwctx;		/*%< lightweight proto context */
187170222Sdougb	isc_task_t	       *task;		/*%< owning task */
188135446Strhodes	unsigned int		flags;
189135446Strhodes	ISC_LINK(ns_lwdclientmgr_t)	link;
190170222Sdougb	ISC_LIST(ns_lwdclient_t)	idle;		/*%< idle client slots */
191170222Sdougb	ISC_LIST(ns_lwdclient_t)	running;	/*%< running clients */
192135446Strhodes};
193135446Strhodes
194135446Strhodes#define NS_LWDCLIENTMGR_FLAGRECVPENDING		0x00000001
195135446Strhodes#define NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN	0x00000002
196135446Strhodes
197135446Strhodesisc_result_t
198135446Strhodesns_lwdclientmgr_create(ns_lwreslistener_t *, unsigned int, isc_taskmgr_t *);
199135446Strhodes
200135446Strhodesvoid
201135446Strhodesns_lwdclient_initialize(ns_lwdclient_t *, ns_lwdclientmgr_t *);
202135446Strhodes
203135446Strhodesisc_result_t
204135446Strhodesns_lwdclient_startrecv(ns_lwdclientmgr_t *);
205135446Strhodes
206135446Strhodesvoid
207135446Strhodesns_lwdclient_stateidle(ns_lwdclient_t *);
208135446Strhodes
209135446Strhodesvoid
210135446Strhodesns_lwdclient_recv(isc_task_t *, isc_event_t *);
211135446Strhodes
212135446Strhodesvoid
213135446Strhodesns_lwdclient_shutdown(isc_task_t *, isc_event_t *);
214135446Strhodes
215135446Strhodesvoid
216135446Strhodesns_lwdclient_send(isc_task_t *, isc_event_t *);
217135446Strhodes
218135446Strhodesisc_result_t
219135446Strhodesns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r);
220135446Strhodes
221135446Strhodes/*
222135446Strhodes * Processing functions of various types.
223135446Strhodes */
224135446Strhodesvoid ns_lwdclient_processgabn(ns_lwdclient_t *, lwres_buffer_t *);
225135446Strhodesvoid ns_lwdclient_processgnba(ns_lwdclient_t *, lwres_buffer_t *);
226135446Strhodesvoid ns_lwdclient_processgrbn(ns_lwdclient_t *, lwres_buffer_t *);
227135446Strhodesvoid ns_lwdclient_processnoop(ns_lwdclient_t *, lwres_buffer_t *);
228135446Strhodes
229135446Strhodesvoid ns_lwdclient_errorpktsend(ns_lwdclient_t *, isc_uint32_t);
230135446Strhodes
231135446Strhodesvoid ns_lwdclient_log(int level, const char *format, ...)
232135446Strhodes     ISC_FORMAT_PRINTF(2, 3);
233135446Strhodes
234135446Strhodes#endif /* NAMED_LWDCLIENT_H */
235