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