1 /* $NetBSD: client.h,v 1.6 2014/12/10 04:37:52 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2003 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: client.h,v 1.96 2012/01/31 23:47:31 tbox Exp */ 21 22 #ifndef NAMED_CLIENT_H 23 #define NAMED_CLIENT_H 1 24 25 /***** 26 ***** Module Info 27 *****/ 28 29 /*! \file 30 * \brief 31 * This module defines two objects, ns_client_t and ns_clientmgr_t. 32 * 33 * An ns_client_t object handles incoming DNS requests from clients 34 * on a given network interface. 35 * 36 * Each ns_client_t object can handle only one TCP connection or UDP 37 * request at a time. Therefore, several ns_client_t objects are 38 * typically created to serve each network interface, e.g., one 39 * for handling TCP requests and a few (one per CPU) for handling 40 * UDP requests. 41 * 42 * Incoming requests are classified as queries, zone transfer 43 * requests, update requests, notify requests, etc, and handed off 44 * to the appropriate request handler. When the request has been 45 * fully handled (which can be much later), the ns_client_t must be 46 * notified of this by calling one of the following functions 47 * exactly once in the context of its task: 48 * \code 49 * ns_client_send() (sending a non-error response) 50 * ns_client_sendraw() (sending a raw response) 51 * ns_client_error() (sending an error response) 52 * ns_client_next() (sending no response) 53 *\endcode 54 * This will release any resources used by the request and 55 * and allow the ns_client_t to listen for the next request. 56 * 57 * A ns_clientmgr_t manages a number of ns_client_t objects. 58 * New ns_client_t objects are created by calling 59 * ns_clientmgr_createclients(). They are destroyed by 60 * destroying their manager. 61 */ 62 63 /*** 64 *** Imports 65 ***/ 66 67 #include <isc/buffer.h> 68 #include <isc/magic.h> 69 #include <isc/stdtime.h> 70 #include <isc/quota.h> 71 #include <isc/queue.h> 72 73 #include <dns/db.h> 74 #include <dns/fixedname.h> 75 #include <dns/name.h> 76 #include <dns/rdataclass.h> 77 #include <dns/rdatatype.h> 78 #include <dns/tcpmsg.h> 79 #include <dns/types.h> 80 81 #include <named/types.h> 82 #include <named/query.h> 83 84 /*** 85 *** Types 86 ***/ 87 88 /*% nameserver client structure */ 89 struct ns_client { 90 unsigned int magic; 91 isc_mem_t * mctx; 92 ns_clientmgr_t * manager; 93 int state; 94 int newstate; 95 int naccepts; 96 int nreads; 97 int nsends; 98 int nrecvs; 99 int nupdates; 100 int nctls; 101 int references; 102 isc_boolean_t needshutdown; /* 103 * Used by clienttest to get 104 * the client to go from 105 * inactive to free state 106 * by shutting down the 107 * client's task. 108 */ 109 unsigned int attributes; 110 isc_task_t * task; 111 dns_view_t * view; 112 dns_dispatch_t * dispatch; 113 isc_socket_t * udpsocket; 114 isc_socket_t * tcplistener; 115 isc_socket_t * tcpsocket; 116 unsigned char * tcpbuf; 117 dns_tcpmsg_t tcpmsg; 118 isc_boolean_t tcpmsg_valid; 119 isc_timer_t * timer; 120 isc_timer_t * delaytimer; 121 isc_boolean_t timerset; 122 dns_message_t * message; 123 isc_socketevent_t * sendevent; 124 isc_socketevent_t * recvevent; 125 unsigned char * recvbuf; 126 dns_rdataset_t * opt; 127 isc_uint16_t udpsize; 128 isc_uint16_t extflags; 129 isc_int16_t ednsversion; /* -1 noedns */ 130 void (*next)(ns_client_t *); 131 void (*shutdown)(void *arg, isc_result_t result); 132 void *shutdown_arg; 133 ns_query_t query; 134 isc_stdtime_t requesttime; 135 isc_stdtime_t now; 136 dns_name_t signername; /*%< [T]SIG key name */ 137 dns_name_t * signer; /*%< NULL if not valid sig */ 138 isc_boolean_t mortal; /*%< Die after handling request */ 139 isc_quota_t *tcpquota; 140 isc_quota_t *recursionquota; 141 ns_interface_t *interface; 142 isc_sockaddr_t peeraddr; 143 isc_boolean_t peeraddr_valid; 144 isc_netaddr_t destaddr; 145 struct in6_pktinfo pktinfo; 146 isc_dscp_t dscp; 147 isc_event_t ctlevent; 148 #ifdef ALLOW_FILTER_AAAA 149 dns_aaaa_t filter_aaaa; 150 #endif 151 /*% 152 * Information about recent FORMERR response(s), for 153 * FORMERR loop avoidance. This is separate for each 154 * client object rather than global only to avoid 155 * the need for locking. 156 */ 157 struct { 158 isc_sockaddr_t addr; 159 isc_stdtime_t time; 160 dns_messageid_t id; 161 } formerrcache; 162 163 ISC_LINK(ns_client_t) link; 164 ISC_LINK(ns_client_t) rlink; 165 ISC_QLINK(ns_client_t) ilink; 166 unsigned char cookie[8]; 167 isc_uint32_t expire; 168 }; 169 170 typedef ISC_QUEUE(ns_client_t) client_queue_t; 171 typedef ISC_LIST(ns_client_t) client_list_t; 172 173 #define NS_CLIENT_MAGIC ISC_MAGIC('N','S','C','c') 174 #define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC) 175 176 #define NS_CLIENTATTR_TCP 0x0001 177 #define NS_CLIENTATTR_RA 0x0002 /*%< Client gets recursive service */ 178 #define NS_CLIENTATTR_PKTINFO 0x0004 /*%< pktinfo is valid */ 179 #define NS_CLIENTATTR_MULTICAST 0x0008 /*%< recv'd from multicast */ 180 #define NS_CLIENTATTR_WANTDNSSEC 0x0010 /*%< include dnssec records */ 181 #define NS_CLIENTATTR_WANTNSID 0x0020 /*%< include nameserver ID */ 182 #ifdef ALLOW_FILTER_AAAA 183 #define NS_CLIENTATTR_FILTER_AAAA 0x0040 /*%< suppress AAAAs */ 184 #define NS_CLIENTATTR_FILTER_AAAA_RC 0x0080 /*%< recursing for A against AAAA */ 185 #endif 186 #define NS_CLIENTATTR_WANTAD 0x0100 /*%< want AD in response if possible */ 187 #define NS_CLIENTATTR_WANTSIT 0x0200 /*%< include SIT */ 188 #define NS_CLIENTATTR_HAVESIT 0x0400 /*%< has a valid SIT */ 189 #define NS_CLIENTATTR_WANTEXPIRE 0x0800 /*%< return seconds to expire */ 190 #define NS_CLIENTATTR_HAVEEXPIRE 0x1000 /*%< return seconds to expire */ 191 #define NS_CLIENTATTR_WANTOPT 0x2000 /*%< add opt to reply */ 192 193 extern unsigned int ns_client_requests; 194 195 /*** 196 *** Functions 197 ***/ 198 199 /*% 200 * Note! These ns_client_ routines MUST be called ONLY from the client's 201 * task in order to ensure synchronization. 202 */ 203 204 void 205 ns_client_send(ns_client_t *client); 206 /*% 207 * Finish processing the current client request and 208 * send client->message as a response. 209 * \brief 210 * Note! These ns_client_ routines MUST be called ONLY from the client's 211 * task in order to ensure synchronization. 212 */ 213 214 void 215 ns_client_sendraw(ns_client_t *client, dns_message_t *msg); 216 /*% 217 * Finish processing the current client request and 218 * send msg as a response using client->message->id for the id. 219 */ 220 221 void 222 ns_client_error(ns_client_t *client, isc_result_t result); 223 /*% 224 * Finish processing the current client request and return 225 * an error response to the client. The error response 226 * will have an RCODE determined by 'result'. 227 */ 228 229 void 230 ns_client_next(ns_client_t *client, isc_result_t result); 231 /*% 232 * Finish processing the current client request, 233 * return no response to the client. 234 */ 235 236 isc_boolean_t 237 ns_client_shuttingdown(ns_client_t *client); 238 /*% 239 * Return ISC_TRUE iff the client is currently shutting down. 240 */ 241 242 void 243 ns_client_attach(ns_client_t *source, ns_client_t **target); 244 /*% 245 * Attach '*targetp' to 'source'. 246 */ 247 248 void 249 ns_client_detach(ns_client_t **clientp); 250 /*% 251 * Detach '*clientp' from its client. 252 */ 253 254 isc_result_t 255 ns_client_replace(ns_client_t *client); 256 /*% 257 * Try to replace the current client with a new one, so that the 258 * current one can go off and do some lengthy work without 259 * leaving the dispatch/socket without service. 260 */ 261 262 void 263 ns_client_settimeout(ns_client_t *client, unsigned int seconds); 264 /*% 265 * Set a timer in the client to go off in the specified amount of time. 266 */ 267 268 isc_result_t 269 ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, 270 isc_timermgr_t *timermgr, ns_clientmgr_t **managerp); 271 /*% 272 * Create a client manager. 273 */ 274 275 void 276 ns_clientmgr_destroy(ns_clientmgr_t **managerp); 277 /*% 278 * Destroy a client manager and all ns_client_t objects 279 * managed by it. 280 */ 281 282 isc_result_t 283 ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, 284 ns_interface_t *ifp, isc_boolean_t tcp); 285 /*% 286 * Create up to 'n' clients listening on interface 'ifp'. 287 * If 'tcp' is ISC_TRUE, the clients will listen for TCP connections, 288 * otherwise for UDP requests. 289 */ 290 291 isc_sockaddr_t * 292 ns_client_getsockaddr(ns_client_t *client); 293 /*% 294 * Get the socket address of the client whose request is 295 * currently being processed. 296 */ 297 298 isc_result_t 299 ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr, 300 dns_acl_t *acl, isc_boolean_t default_allow); 301 302 /*% 303 * Convenience function for client request ACL checking. 304 * 305 * Check the current client request against 'acl'. If 'acl' 306 * is NULL, allow the request iff 'default_allow' is ISC_TRUE. 307 * If netaddr is NULL, check the ACL against client->peeraddr; 308 * otherwise check it against netaddr. 309 * 310 * Notes: 311 *\li This is appropriate for checking allow-update, 312 * allow-query, allow-transfer, etc. It is not appropriate 313 * for checking the blackhole list because we treat positive 314 * matches as "allow" and negative matches as "deny"; in 315 * the case of the blackhole list this would be backwards. 316 * 317 * Requires: 318 *\li 'client' points to a valid client. 319 *\li 'netaddr' points to a valid address, or is NULL. 320 *\li 'acl' points to a valid ACL, or is NULL. 321 * 322 * Returns: 323 *\li ISC_R_SUCCESS if the request should be allowed 324 * \li DNS_R_REFUSED if the request should be denied 325 *\li No other return values are possible. 326 */ 327 328 isc_result_t 329 ns_client_checkacl(ns_client_t *client, 330 isc_sockaddr_t *sockaddr, 331 const char *opname, dns_acl_t *acl, 332 isc_boolean_t default_allow, 333 int log_level); 334 /*% 335 * Like ns_client_checkaclsilent, except the outcome of the check is 336 * logged at log level 'log_level' if denied, and at debug 3 if approved. 337 * Log messages will refer to the request as an 'opname' request. 338 * 339 * Requires: 340 *\li 'client' points to a valid client. 341 *\li 'sockaddr' points to a valid address, or is NULL. 342 *\li 'acl' points to a valid ACL, or is NULL. 343 *\li 'opname' points to a null-terminated string. 344 */ 345 346 void 347 ns_client_log(ns_client_t *client, isc_logcategory_t *category, 348 isc_logmodule_t *module, int level, 349 const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); 350 351 void 352 ns_client_logv(ns_client_t *client, isc_logcategory_t *category, 353 isc_logmodule_t *module, int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0); 354 355 void 356 ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, 357 dns_rdataclass_t rdclass, char *buf, size_t len); 358 359 #define NS_CLIENT_ACLMSGSIZE(x) \ 360 (DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \ 361 DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'")) 362 363 void 364 ns_client_recursing(ns_client_t *client); 365 /*% 366 * Add client to end of th recursing list. 367 */ 368 369 void 370 ns_client_killoldestquery(ns_client_t *client); 371 /*% 372 * Kill the oldest recursive query (recursing list head). 373 */ 374 375 void 376 ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager); 377 /*% 378 * Dump the outstanding recursive queries to 'f'. 379 */ 380 381 void 382 ns_client_qnamereplace(ns_client_t *client, dns_name_t *name); 383 /*% 384 * Replace the qname. 385 */ 386 387 isc_boolean_t 388 ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, 389 isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, 390 dns_rdataclass_t rdclass, void *arg); 391 /*% 392 * Isself callback. 393 */ 394 395 isc_result_t 396 ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp); 397 398 isc_result_t 399 ns_client_addopt(ns_client_t *client, dns_message_t *message, 400 dns_rdataset_t **opt); 401 402 #endif /* NAMED_CLIENT_H */ 403