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