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