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