2 * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: lwdclient.h,v 1.20 2009-01-17 23:47:42 tbox Exp $ */
20 #ifndef NAMED_LWDCLIENT_H
21 #define NAMED_LWDCLIENT_H 1
25 #include <isc/event.h>
26 #include <isc/eventclass.h>
27 #include <isc/netaddr.h>
28 #include <isc/sockaddr.h>
29 #include <isc/types.h>
31 #include <dns/fixedname.h>
32 #include <dns/types.h>
34 #include <lwres/lwres.h>
36 #include <named/lwsearch.h>
38 #define LWRD_EVENTCLASS ISC_EVENTCLASS(4242)
40 #define LWRD_SHUTDOWN (LWRD_EVENTCLASS + 0x0001)
42 /*% Lightweight Resolver Daemon Client */
44 isc_sockaddr_t address; /*%< where to reply */
45 struct in6_pktinfo pktinfo;
46 isc_boolean_t pktinfo_valid;
47 ns_lwdclientmgr_t *clientmgr; /*%< our parent */
48 ISC_LINK(ns_lwdclient_t) link;
50 void *arg; /*%< packet processing state */
55 unsigned char buffer[LWRES_RECVLENGTH]; /*%< receive buffer */
56 isc_uint32_t recvlength; /*%< length recv'd */
60 * Send data state. If sendbuf != buffer (that is, the send buffer
61 * isn't our receive buffer) it will be freed to the lwres_context_t.
63 unsigned char *sendbuf;
64 isc_uint32_t sendlength;
65 isc_buffer_t recv_buffer;
68 * gabn (get address by name) state info.
71 dns_adbfind_t *v4find;
72 dns_adbfind_t *v6find;
73 unsigned int find_wanted; /*%< Addresses we want */
74 dns_fixedname_t query_name;
75 dns_fixedname_t target_name;
76 ns_lwsearchctx_t searchctx;
77 lwres_gabnresponse_t gabn;
80 * gnba (get name by address) state info.
82 lwres_gnbaresponse_t gnba;
88 * grbn (get rrset by name) state info.
90 * Note: this also uses target_name and searchctx.
92 lwres_grbnresponse_t grbn;
94 dns_rdatatype_t rdtype;
97 * Alias and address info. This is copied up to the gabn/gnba
98 * structures eventually.
100 * XXXMLG We can keep all of this in a client since we only service
101 * three packet types right now. If we started handling more,
102 * we'd need to use "arg" above and allocate/destroy things.
104 char *aliases[LWRES_MAX_ALIASES];
105 isc_uint16_t aliaslen[LWRES_MAX_ALIASES];
106 lwres_addr_t addrs[LWRES_MAX_ADDRS];
112 * _IDLE The client is not doing anything at all.
114 * _RECV The client is waiting for data after issuing a socket recv().
116 * _RECVDONE Data has been received, and is being processed.
118 * _FINDWAIT An adb (or other) request was made that cannot be satisfied
119 * immediately. An event will wake the client up.
121 * _SEND All data for a response has completed, and a reply was
122 * sent via a socket send() call.
124 * Badly formatted state table:
126 * IDLE -> RECV when client has a recv() queued.
128 * RECV -> RECVDONE when recvdone event received.
130 * RECVDONE -> SEND if the data for a reply is at hand.
131 * RECVDONE -> FINDWAIT if more searching is needed, and events will
132 * eventually wake us up again.
134 * FINDWAIT -> SEND when enough data was received to reply.
136 * SEND -> IDLE when a senddone event was received.
138 * At any time -> IDLE on error. Sometimes this will be -> SEND
139 * instead, if enough data is on hand to reply with a meaningful
142 * Packets which are badly formatted may or may not get error returns.
144 #define NS_LWDCLIENT_STATEIDLE 1
145 #define NS_LWDCLIENT_STATERECV 2
146 #define NS_LWDCLIENT_STATERECVDONE 3
147 #define NS_LWDCLIENT_STATEFINDWAIT 4
148 #define NS_LWDCLIENT_STATESEND 5
149 #define NS_LWDCLIENT_STATESENDDONE 6
151 #define NS_LWDCLIENT_ISIDLE(c) \
152 ((c)->state == NS_LWDCLIENT_STATEIDLE)
153 #define NS_LWDCLIENT_ISRECV(c) \
154 ((c)->state == NS_LWDCLIENT_STATERECV)
155 #define NS_LWDCLIENT_ISRECVDONE(c) \
156 ((c)->state == NS_LWDCLIENT_STATERECVDONE)
157 #define NS_LWDCLIENT_ISFINDWAIT(c) \
158 ((c)->state == NS_LWDCLIENT_STATEFINDWAIT)
159 #define NS_LWDCLIENT_ISSEND(c) \
160 ((c)->state == NS_LWDCLIENT_STATESEND)
163 * Overall magic test that means we're not idle.
165 #define NS_LWDCLIENT_ISRUNNING(c) (!NS_LWDCLIENT_ISIDLE(c))
167 #define NS_LWDCLIENT_SETIDLE(c) \
168 ((c)->state = NS_LWDCLIENT_STATEIDLE)
169 #define NS_LWDCLIENT_SETRECV(c) \
170 ((c)->state = NS_LWDCLIENT_STATERECV)
171 #define NS_LWDCLIENT_SETRECVDONE(c) \
172 ((c)->state = NS_LWDCLIENT_STATERECVDONE)
173 #define NS_LWDCLIENT_SETFINDWAIT(c) \
174 ((c)->state = NS_LWDCLIENT_STATEFINDWAIT)
175 #define NS_LWDCLIENT_SETSEND(c) \
176 ((c)->state = NS_LWDCLIENT_STATESEND)
177 #define NS_LWDCLIENT_SETSENDDONE(c) \
178 ((c)->state = NS_LWDCLIENT_STATESENDDONE)
180 /*% lightweight daemon client manager */
181 struct ns_lwdclientmgr {
182 ns_lwreslistener_t *listener;
184 isc_socket_t *sock; /*%< socket to use */
186 lwres_context_t *lwctx; /*%< lightweight proto context */
187 isc_task_t *task; /*%< owning task */
189 ISC_LINK(ns_lwdclientmgr_t) link;
190 ISC_LIST(ns_lwdclient_t) idle; /*%< idle client slots */
191 ISC_LIST(ns_lwdclient_t) running; /*%< running clients */
194 #define NS_LWDCLIENTMGR_FLAGRECVPENDING 0x00000001
195 #define NS_LWDCLIENTMGR_FLAGSHUTTINGDOWN 0x00000002
198 ns_lwdclientmgr_create(ns_lwreslistener_t *, unsigned int, isc_taskmgr_t *);
201 ns_lwdclient_initialize(ns_lwdclient_t *, ns_lwdclientmgr_t *);
204 ns_lwdclient_startrecv(ns_lwdclientmgr_t *);
207 ns_lwdclient_stateidle(ns_lwdclient_t *);
210 ns_lwdclient_recv(isc_task_t *, isc_event_t *);
213 ns_lwdclient_shutdown(isc_task_t *, isc_event_t *);
216 ns_lwdclient_send(isc_task_t *, isc_event_t *);
219 ns_lwdclient_sendreply(ns_lwdclient_t *client, isc_region_t *r);
222 * Processing functions of various types.
224 void ns_lwdclient_processgabn(ns_lwdclient_t *, lwres_buffer_t *);
225 void ns_lwdclient_processgnba(ns_lwdclient_t *, lwres_buffer_t *);
226 void ns_lwdclient_processgrbn(ns_lwdclient_t *, lwres_buffer_t *);
227 void ns_lwdclient_processnoop(ns_lwdclient_t *, lwres_buffer_t *);
229 void ns_lwdclient_errorpktsend(ns_lwdclient_t *, isc_uint32_t);
231 void ns_lwdclient_log(int level, const char *format, ...)
232 ISC_FORMAT_PRINTF(2, 3);
234 #endif /* NAMED_LWDCLIENT_H */