client.h 11.9 KB
Newer Older
Bob Halley's avatar
add  
Bob Halley committed
1
/*
2
 * Copyright (C) 2004-2009, 2011-2015  Internet Systems Consortium, Inc. ("ISC")
Mark Andrews's avatar
Mark Andrews committed
3
 * Copyright (C) 1999-2003  Internet Software Consortium.
4
 *
Automatic Updater's avatar
Automatic Updater committed
5
 * Permission to use, copy, modify, and/or distribute this software for any
Bob Halley's avatar
add  
Bob Halley committed
6 7
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
8
 *
Mark Andrews's avatar
Mark Andrews committed
9 10 11 12 13 14 15
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
Bob Halley's avatar
add  
Bob Halley committed
16 17
 */

Automatic Updater's avatar
Automatic Updater committed
18
/* $Id: client.h,v 1.96 2012/01/31 23:47:31 tbox Exp $ */
David Lawrence's avatar
David Lawrence committed
19

20 21
#ifndef NAMED_CLIENT_H
#define NAMED_CLIENT_H 1
Bob Halley's avatar
add  
Bob Halley committed
22

23 24 25 26
/*****
 ***** Module Info
 *****/

Automatic Updater's avatar
Automatic Updater committed
27
/*! \file
28
 * \brief
29 30
 * This module defines two objects, ns_client_t and ns_clientmgr_t.
 *
Andreas Gustafsson's avatar
Andreas Gustafsson committed
31 32
 * An ns_client_t object handles incoming DNS requests from clients
 * on a given network interface.
33 34 35
 *
 * Each ns_client_t object can handle only one TCP connection or UDP
 * request at a time.  Therefore, several ns_client_t objects are
Andreas Gustafsson's avatar
Andreas Gustafsson committed
36
 * typically created to serve each network interface, e.g., one
37
 * for handling TCP requests and a few (one per CPU) for handling
Andreas Gustafsson's avatar
Andreas Gustafsson committed
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 44
 * fully handled (which can be much later), the ns_client_t must be
 * 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 50
 *   ns_client_error()	(sending an error response)
 *   ns_client_next()	(sending no response)
51
 *\endcode
52
 * This will release any resources used by the request and
53 54 55 56
 * and allow the ns_client_t to listen for the next request.
 *
 * A ns_clientmgr_t manages a number of ns_client_t objects.
 * New ns_client_t objects are created by calling
57 58
 * ns_clientmgr_createclients(). They are destroyed by
 * destroying their manager.
59 60 61 62 63 64
 */

/***
 *** Imports
 ***/

Bob Halley's avatar
add  
Bob Halley committed
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>
Bob Halley's avatar
add  
Bob Halley committed
70

71
#include <dns/db.h>
72
#include <dns/fixedname.h>
73
#include <dns/name.h>
74 75
#include <dns/rdataclass.h>
#include <dns/rdatatype.h>
Bob Halley's avatar
Bob Halley committed
76
#include <dns/tcpmsg.h>
77 78
#include <dns/types.h>

Bob Halley's avatar
add  
Bob Halley committed
79
#include <named/types.h>
Bob Halley's avatar
Bob Halley committed
80
#include <named/query.h>
Bob Halley's avatar
add  
Bob Halley committed
81

82 83 84
/***
 *** Types
 ***/
Bob Halley's avatar
add  
Bob Halley committed
85

86
/*% nameserver client structure */
Bob Halley's avatar
add  
Bob Halley committed
87
struct ns_client {
88 89 90 91 92 93 94 95
	unsigned int		magic;
	isc_mem_t *		mctx;
	ns_clientmgr_t *	manager;
	int			state;
	int			newstate;
	int			naccepts;
	int			nreads;
	int			nsends;
96
	int			nrecvs;
97
	int			nupdates;
98
	int			nctls;
99
	int			references;
100 101 102 103 104 105 106
	isc_boolean_t		needshutdown; 	/*
						 * Used by clienttest to get
						 * the client to go from
						 * inactive to free state
						 * by shutting down the
						 * client's task.
						 */
107 108 109 110
	unsigned int		attributes;
	isc_task_t *		task;
	dns_view_t *		view;
	dns_dispatch_t *	dispatch;
111
	isc_socket_t *		udpsocket;
112 113
	isc_socket_t *		tcplistener;
	isc_socket_t *		tcpsocket;
114
	unsigned char *		tcpbuf;
115 116 117
	dns_tcpmsg_t		tcpmsg;
	isc_boolean_t		tcpmsg_valid;
	isc_timer_t *		timer;
118
	isc_timer_t *		delaytimer;
119
	isc_boolean_t 		timerset;
120
	dns_message_t *		message;
121 122
	isc_socketevent_t *	sendevent;
	isc_socketevent_t *	recvevent;
123
	unsigned char *		recvbuf;
124 125
	dns_rdataset_t *	opt;
	isc_uint16_t		udpsize;
126
	isc_uint16_t		extflags;
127
	isc_int16_t		ednsversion;	/* -1 noedns */
128 129 130 131
	void			(*next)(ns_client_t *);
	void			(*shutdown)(void *arg, isc_result_t result);
	void 			*shutdown_arg;
	ns_query_t		query;
Evan Hunt's avatar
Evan Hunt committed
132
	isc_time_t		requesttime;
133
	isc_stdtime_t		now;
Evan Hunt's avatar
Evan Hunt committed
134
	isc_time_t		tnow;
135 136 137
	dns_name_t		signername;   /*%< [T]SIG key name */
	dns_name_t *		signer;	      /*%< NULL if not valid sig */
	isc_boolean_t		mortal;	      /*%< Die after handling request */
138
	isc_boolean_t		pipelined;   /*%< TCP queries not in sequence */
139 140 141
	isc_quota_t		*tcpquota;
	isc_quota_t		*recursionquota;
	ns_interface_t		*interface;
Evan Hunt's avatar
Evan Hunt committed
142

143 144
	isc_sockaddr_t		peeraddr;
	isc_boolean_t		peeraddr_valid;
145
	isc_netaddr_t		destaddr;
Evan Hunt's avatar
Evan Hunt committed
146 147 148 149 150

	isc_netaddr_t		ecs_addr;	/*%< EDNS client subnet */
	isc_uint8_t		ecs_addrlen;
	isc_uint8_t		ecs_scope;

151
	struct in6_pktinfo	pktinfo;
Evan Hunt's avatar
Evan Hunt committed
152
	isc_dscp_t		dscp;
153
	isc_event_t		ctlevent;
Evan Hunt's avatar
Evan Hunt committed
154 155
#ifdef ALLOW_FILTER_AAAA
	dns_aaaa_t		filter_aaaa;
156
#endif
157
	/*%
158 159 160 161 162 163 164 165 166 167
	 * Information about recent FORMERR response(s), for
	 * FORMERR loop avoidance.  This is separate for each
	 * client object rather than global only to avoid
	 * the need for locking.
	 */
	struct {
		isc_sockaddr_t		addr;
		isc_stdtime_t		time;
		dns_messageid_t		id;
	} formerrcache;
168

169
	ISC_LINK(ns_client_t)	link;
170 171
	ISC_LINK(ns_client_t)	rlink;
	ISC_QLINK(ns_client_t)	ilink;
172
	unsigned char		cookie[8];
173
	isc_uint32_t		expire;
Bob Halley's avatar
add  
Bob Halley committed
174 175
};

176 177 178
typedef ISC_QUEUE(ns_client_t) client_queue_t;
typedef ISC_LIST(ns_client_t) client_list_t;

179
#define NS_CLIENT_MAGIC			ISC_MAGIC('N','S','C','c')
180
#define NS_CLIENT_VALID(c)		ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
Bob Halley's avatar
add  
Bob Halley committed
181

182 183 184 185 186 187
#define NS_CLIENTATTR_TCP		0x0001
#define NS_CLIENTATTR_RA		0x0002 /*%< Client gets recursive service */
#define NS_CLIENTATTR_PKTINFO		0x0004 /*%< pktinfo is valid */
#define NS_CLIENTATTR_MULTICAST		0x0008 /*%< recv'd from multicast */
#define NS_CLIENTATTR_WANTDNSSEC	0x0010 /*%< include dnssec records */
#define NS_CLIENTATTR_WANTNSID          0x0020 /*%< include nameserver ID */
Evan Hunt's avatar
Evan Hunt committed
188
#ifdef ALLOW_FILTER_AAAA
189 190
#define NS_CLIENTATTR_FILTER_AAAA	0x0040 /*%< suppress AAAAs */
#define NS_CLIENTATTR_FILTER_AAAA_RC	0x0080 /*%< recursing for A against AAAA */
191
#endif
192
#define NS_CLIENTATTR_WANTAD		0x0100 /*%< want AD in response if possible */
193 194
#define NS_CLIENTATTR_WANTCOOKIE	0x0200 /*%< return a COOKIE */
#define NS_CLIENTATTR_HAVECOOKIE	0x0400 /*%< has a valid COOKIE */
195 196 197
#define NS_CLIENTATTR_WANTEXPIRE	0x0800 /*%< return seconds to expire */
#define NS_CLIENTATTR_HAVEEXPIRE	0x1000 /*%< return seconds to expire */
#define NS_CLIENTATTR_WANTOPT		0x2000 /*%< add opt to reply */
Evan Hunt's avatar
Evan Hunt committed
198
#define NS_CLIENTATTR_HAVEECS		0x4000 /*%< sent an ECS option */
199

200
#define NS_CLIENTATTR_NOSETFC		0x8000 /*%< don't set servfail cache */
Evan Hunt's avatar
Evan Hunt committed
201 202 203 204 205 206 207 208 209

/*
 * Flag to use with the SERVFAIL cache to indicate
 * that a query had the CD bit set.
 */
#define NS_FAILCACHE_CD		0x01



210
extern unsigned int ns_client_requests;
Bob Halley's avatar
Bob Halley committed
211

212 213 214 215
/***
 *** Functions
 ***/

216
/*%
Bob Halley's avatar
add  
Bob Halley committed
217 218 219
 * Note!  These ns_client_ routines MUST be called ONLY from the client's
 * task in order to ensure synchronization.
 */
Andreas Gustafsson's avatar
Andreas Gustafsson committed
220

Bob Halley's avatar
add  
Bob Halley committed
221
void
Andreas Gustafsson's avatar
Andreas Gustafsson committed
222
ns_client_send(ns_client_t *client);
223
/*%
Andreas Gustafsson's avatar
Andreas Gustafsson committed
224 225
 * Finish processing the current client request and
 * send client->message as a response.
226 227 228
 * \brief
 * Note!  These ns_client_ routines MUST be called ONLY from the client's
 * task in order to ensure synchronization.
Andreas Gustafsson's avatar
Andreas Gustafsson committed
229
 */
Bob Halley's avatar
add  
Bob Halley committed
230

231 232
void
ns_client_sendraw(ns_client_t *client, dns_message_t *msg);
233
/*%
234
 * Finish processing the current client request and
235
 * send msg as a response using client->message->id for the id.
236 237
 */

Bob Halley's avatar
add  
Bob Halley committed
238
void
Andreas Gustafsson's avatar
Andreas Gustafsson committed
239
ns_client_error(ns_client_t *client, isc_result_t result);
240
/*%
Andreas Gustafsson's avatar
Andreas Gustafsson committed
241 242 243 244
 * Finish processing the current client request and return
 * an error response to the client.  The error response
 * will have an RCODE determined by 'result'.
 */
Bob Halley's avatar
add  
Bob Halley committed
245

Bob Halley's avatar
Bob Halley committed
246
void
Andreas Gustafsson's avatar
Andreas Gustafsson committed
247
ns_client_next(ns_client_t *client, isc_result_t result);
248
/*%
249
 * Finish processing the current client request,
Andreas Gustafsson's avatar
Andreas Gustafsson committed
250 251
 * return no response to the client.
 */
Bob Halley's avatar
Bob Halley committed
252

253 254
isc_boolean_t
ns_client_shuttingdown(ns_client_t *client);
255
/*%
256 257 258
 * Return ISC_TRUE iff the client is currently shutting down.
 */

259
void
260
ns_client_attach(ns_client_t *source, ns_client_t **target);
261
/*%
262
 * Attach '*targetp' to 'source'.
263
 */
264

265
void
266
ns_client_detach(ns_client_t **clientp);
267
/*%
268
 * Detach '*clientp' from its client.
269 270 271
 */

isc_result_t
272
ns_client_replace(ns_client_t *client);
273
/*%
274 275 276 277
 * Try to replace the current client with a new one, so that the
 * current one can go off and do some lengthy work without
 * leaving the dispatch/socket without service.
 */
278

279 280
void
ns_client_settimeout(ns_client_t *client, unsigned int seconds);
281
/*%
282 283 284
 * Set a timer in the client to go off in the specified amount of time.
 */

Bob Halley's avatar
add  
Bob Halley committed
285 286 287
isc_result_t
ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
		    isc_timermgr_t *timermgr, ns_clientmgr_t **managerp);
288
/*%
Andreas Gustafsson's avatar
Andreas Gustafsson committed
289 290
 * Create a client manager.
 */
Bob Halley's avatar
add  
Bob Halley committed
291 292 293

void
ns_clientmgr_destroy(ns_clientmgr_t **managerp);
294
/*%
Andreas Gustafsson's avatar
Andreas Gustafsson committed
295 296 297
 * Destroy a client manager and all ns_client_t objects
 * managed by it.
 */
Bob Halley's avatar
add  
Bob Halley committed
298 299

isc_result_t
300 301
ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n,
			   ns_interface_t *ifp, isc_boolean_t tcp);
302
/*%
303 304 305
 * Create up to 'n' clients listening on interface 'ifp'.
 * If 'tcp' is ISC_TRUE, the clients will listen for TCP connections,
 * otherwise for UDP requests.
306
 */
Bob Halley's avatar
Bob Halley committed
307

308 309
isc_sockaddr_t *
ns_client_getsockaddr(ns_client_t *client);
310
/*%
Andreas Gustafsson's avatar
Andreas Gustafsson committed
311 312 313
 * Get the socket address of the client whose request is
 * currently being processed.
 */
314

315
isc_result_t
316 317
ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
			 dns_acl_t *acl, isc_boolean_t default_allow);
318

319
/*%
320 321 322 323
 * Convenience function for client request ACL checking.
 *
 * Check the current client request against 'acl'.  If 'acl'
 * is NULL, allow the request iff 'default_allow' is ISC_TRUE.
324 325
 * If netaddr is NULL, check the ACL against client->peeraddr;
 * otherwise check it against netaddr.
326 327
 *
 * Notes:
328
 *\li	This is appropriate for checking allow-update,
329 330 331 332 333 334
 * 	allow-query, allow-transfer, etc.  It is not appropriate
 * 	for checking the blackhole list because we treat positive
 * 	matches as "allow" and negative matches as "deny"; in
 *	the case of the blackhole list this would be backwards.
 *
 * Requires:
335
 *\li	'client' points to a valid client.
336
 *\li	'netaddr' points to a valid address, or is NULL.
337
 *\li	'acl' points to a valid ACL, or is NULL.
338 339
 *
 * Returns:
340
 *\li	ISC_R_SUCCESS	if the request should be allowed
Francis Dupont's avatar
Francis Dupont committed
341
 * \li	DNS_R_REFUSED	if the request should be denied
342
 *\li	No other return values are possible.
343 344
 */

345 346
isc_result_t
ns_client_checkacl(ns_client_t  *client,
347
		   isc_sockaddr_t *sockaddr,
348 349 350
		   const char *opname, dns_acl_t *acl,
		   isc_boolean_t default_allow,
		   int log_level);
351
/*%
352 353 354
 * Like ns_client_checkaclsilent, except the outcome of the check is
 * logged at log level 'log_level' if denied, and at debug 3 if approved.
 * Log messages will refer to the request as an 'opname' request.
355 356
 *
 * Requires:
357 358 359
 *\li	'client' points to a valid client.
 *\li	'sockaddr' points to a valid address, or is NULL.
 *\li	'acl' points to a valid ACL, or is NULL.
360
 *\li	'opname' points to a null-terminated string.
361 362
 */

Andreas Gustafsson's avatar
Andreas Gustafsson committed
363 364 365
void
ns_client_log(ns_client_t *client, isc_logcategory_t *category,
	      isc_logmodule_t *module, int level,
366
	      const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6);
367

368 369 370 371
void
ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
	       isc_logmodule_t *module, int level, const char *fmt, va_list ap) ISC_FORMAT_PRINTF(5, 0);

372
void
373 374 375 376 377 378
ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type,
		 dns_rdataclass_t rdclass, char *buf, size_t len);

#define NS_CLIENT_ACLMSGSIZE(x) \
	(DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \
	 DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'"))
379

380
void
381
ns_client_recursing(ns_client_t *client);
382
/*%
383 384 385 386 387 388 389
 * Add client to end of th recursing list.
 */

void
ns_client_killoldestquery(ns_client_t *client);
/*%
 * Kill the oldest recursive query (recursing list head).
390 391
 */

392 393
void
ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager);
394
/*%
395 396 397
 * Dump the outstanding recursive queries to 'f'.
 */

398 399 400 401 402 403
void
ns_client_qnamereplace(ns_client_t *client, dns_name_t *name);
/*%
 * Replace the qname.
 */

404 405
isc_boolean_t
ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey,
Automatic Updater's avatar
Automatic Updater committed
406 407
		 isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
		 dns_rdataclass_t rdclass, void *arg);
Mark Andrews's avatar
Mark Andrews committed
408
/*%
409 410 411
 * Isself callback.
 */

412 413 414
isc_result_t
ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp);

415 416
isc_result_t
ns_client_addopt(ns_client_t *client, dns_message_t *message,
Tinderbox User's avatar
Tinderbox User committed
417
		 dns_rdataset_t **opt);
418

419
#endif /* NAMED_CLIENT_H */