client.h revision 193149
1/* 2 * Copyright (C) 2004-2009 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: client.h,v 1.86.120.2 2009/01/18 23:47:34 tbox Exp $ */ 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 70#include <dns/fixedname.h> 71#include <dns/name.h> 72#include <dns/rdataclass.h> 73#include <dns/rdatatype.h> 74#include <dns/tcpmsg.h> 75#include <dns/types.h> 76 77#include <named/types.h> 78#include <named/query.h> 79 80/*** 81 *** Types 82 ***/ 83 84typedef ISC_LIST(ns_client_t) client_list_t; 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 struct in6_pktinfo pktinfo; 142 isc_event_t ctlevent; 143 /*% 144 * Information about recent FORMERR response(s), for 145 * FORMERR loop avoidance. This is separate for each 146 * client object rather than global only to avoid 147 * the need for locking. 148 */ 149 struct { 150 isc_sockaddr_t addr; 151 isc_stdtime_t time; 152 dns_messageid_t id; 153 } formerrcache; 154 ISC_LINK(ns_client_t) link; 155 /*% 156 * The list 'link' is part of, or NULL if not on any list. 157 */ 158 client_list_t *list; 159}; 160 161#define NS_CLIENT_MAGIC ISC_MAGIC('N','S','C','c') 162#define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC) 163 164#define NS_CLIENTATTR_TCP 0x01 165#define NS_CLIENTATTR_RA 0x02 /*%< Client gets recursive service */ 166#define NS_CLIENTATTR_PKTINFO 0x04 /*%< pktinfo is valid */ 167#define NS_CLIENTATTR_MULTICAST 0x08 /*%< recv'd from multicast */ 168#define NS_CLIENTATTR_WANTDNSSEC 0x10 /*%< include dnssec records */ 169#define NS_CLIENTATTR_WANTNSID 0x20 /*%< include nameserver ID */ 170 171extern unsigned int ns_client_requests; 172 173/*** 174 *** Functions 175 ***/ 176 177/*% 178 * Note! These ns_client_ routines MUST be called ONLY from the client's 179 * task in order to ensure synchronization. 180 */ 181 182void 183ns_client_send(ns_client_t *client); 184/*% 185 * Finish processing the current client request and 186 * send client->message as a response. 187 * \brief 188 * Note! These ns_client_ routines MUST be called ONLY from the client's 189 * task in order to ensure synchronization. 190 */ 191 192void 193ns_client_sendraw(ns_client_t *client, dns_message_t *msg); 194/*% 195 * Finish processing the current client request and 196 * send msg as a response using client->message->id for the id. 197 */ 198 199void 200ns_client_error(ns_client_t *client, isc_result_t result); 201/*% 202 * Finish processing the current client request and return 203 * an error response to the client. The error response 204 * will have an RCODE determined by 'result'. 205 */ 206 207void 208ns_client_next(ns_client_t *client, isc_result_t result); 209/*% 210 * Finish processing the current client request, 211 * return no response to the client. 212 */ 213 214isc_boolean_t 215ns_client_shuttingdown(ns_client_t *client); 216/*% 217 * Return ISC_TRUE iff the client is currently shutting down. 218 */ 219 220void 221ns_client_attach(ns_client_t *source, ns_client_t **target); 222/*% 223 * Attach '*targetp' to 'source'. 224 */ 225 226void 227ns_client_detach(ns_client_t **clientp); 228/*% 229 * Detach '*clientp' from its client. 230 */ 231 232isc_result_t 233ns_client_replace(ns_client_t *client); 234/*% 235 * Try to replace the current client with a new one, so that the 236 * current one can go off and do some lengthy work without 237 * leaving the dispatch/socket without service. 238 */ 239 240void 241ns_client_settimeout(ns_client_t *client, unsigned int seconds); 242/*% 243 * Set a timer in the client to go off in the specified amount of time. 244 */ 245 246isc_result_t 247ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, 248 isc_timermgr_t *timermgr, ns_clientmgr_t **managerp); 249/*% 250 * Create a client manager. 251 */ 252 253void 254ns_clientmgr_destroy(ns_clientmgr_t **managerp); 255/*% 256 * Destroy a client manager and all ns_client_t objects 257 * managed by it. 258 */ 259 260isc_result_t 261ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, 262 ns_interface_t *ifp, isc_boolean_t tcp); 263/*% 264 * Create up to 'n' clients listening on interface 'ifp'. 265 * If 'tcp' is ISC_TRUE, the clients will listen for TCP connections, 266 * otherwise for UDP requests. 267 */ 268 269isc_sockaddr_t * 270ns_client_getsockaddr(ns_client_t *client); 271/*% 272 * Get the socket address of the client whose request is 273 * currently being processed. 274 */ 275 276isc_result_t 277ns_client_checkaclsilent(ns_client_t *client, 278 isc_sockaddr_t *sockaddr, 279 dns_acl_t *acl, 280 isc_boolean_t default_allow); 281 282/*% 283 * Convenience function for client request ACL checking. 284 * 285 * Check the current client request against 'acl'. If 'acl' 286 * is NULL, allow the request iff 'default_allow' is ISC_TRUE. 287 * If netaddr is NULL, check the ACL against client->peeraddr; 288 * otherwise check it against netaddr. 289 * 290 * Notes: 291 *\li This is appropriate for checking allow-update, 292 * allow-query, allow-transfer, etc. It is not appropriate 293 * for checking the blackhole list because we treat positive 294 * matches as "allow" and negative matches as "deny"; in 295 * the case of the blackhole list this would be backwards. 296 * 297 * Requires: 298 *\li 'client' points to a valid client. 299 *\li 'sockaddr' points to a valid address, or is NULL. 300 *\li 'acl' points to a valid ACL, or is NULL. 301 * 302 * Returns: 303 *\li ISC_R_SUCCESS if the request should be allowed 304 * \li ISC_R_REFUSED if the request should be denied 305 *\li No other return values are possible. 306 */ 307 308isc_result_t 309ns_client_checkacl(ns_client_t *client, 310 isc_sockaddr_t *sockaddr, 311 const char *opname, dns_acl_t *acl, 312 isc_boolean_t default_allow, 313 int log_level); 314/*% 315 * Like ns_client_checkaclsilent, except the outcome of the check is 316 * logged at log level 'log_level' if denied, and at debug 3 if approved. 317 * Log messages will refer to the request as an 'opname' request. 318 * 319 * Requires: 320 *\li 'client' points to a valid client. 321 *\li 'sockaddr' points to a valid address, or is NULL. 322 *\li 'acl' points to a valid ACL, or is NULL. 323 *\li 'opname' points to a null-terminated string. 324 */ 325 326void 327ns_client_log(ns_client_t *client, isc_logcategory_t *category, 328 isc_logmodule_t *module, int level, 329 const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6); 330 331void 332ns_client_logv(ns_client_t *client, isc_logcategory_t *category, 333 isc_logmodule_t *module, int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0); 334 335void 336ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, 337 dns_rdataclass_t rdclass, char *buf, size_t len); 338 339#define NS_CLIENT_ACLMSGSIZE(x) \ 340 (DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \ 341 DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'")) 342 343void 344ns_client_recursing(ns_client_t *client); 345/*% 346 * Add client to end of th recursing list. 347 */ 348 349void 350ns_client_killoldestquery(ns_client_t *client); 351/*% 352 * Kill the oldest recursive query (recursing list head). 353 */ 354 355void 356ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager); 357/*% 358 * Dump the outstanding recursive queries to 'f'. 359 */ 360 361void 362ns_client_qnamereplace(ns_client_t *client, dns_name_t *name); 363/*% 364 * Replace the qname. 365 */ 366 367isc_boolean_t 368ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, 369 isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, 370 dns_rdataclass_t rdclass, void *arg); 371/*% 372 * Isself callback. 373 */ 374 375#endif /* NAMED_CLIENT_H */ 376