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