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