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