1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * SPDX-License-Identifier: MPL-2.0
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9  *
10  * See the COPYRIGHT file distributed with this work for additional
11  * information regarding copyright ownership.
12  */
13 
14 #ifndef NS_CLIENT_H
15 #define NS_CLIENT_H 1
16 
17 /*****
18 ***** Module Info
19 *****/
20 
21 /*! \file
22  * \brief
23  * This module defines two objects, ns_client_t and ns_clientmgr_t.
24  *
25  * An ns_client_t object handles incoming DNS requests from clients
26  * on a given network interface.
27  *
28  * Each ns_client_t object can handle only one TCP connection or UDP
29  * request at a time.  Therefore, several ns_client_t objects are
30  * typically created to serve each network interface, e.g., one
31  * for handling TCP requests and a few (one per CPU) for handling
32  * UDP requests.
33  *
34  * Incoming requests are classified as queries, zone transfer
35  * requests, update requests, notify requests, etc, and handed off
36  * to the appropriate request handler.  When the request has been
37  * fully handled (which can be much later), the ns_client_t must be
38  * notified of this by calling one of the following functions
39  * exactly once in the context of its task:
40  * \code
41  *   ns_client_send()	 (sending a non-error response)
42  *   ns_client_sendraw() (sending a raw response)
43  *   ns_client_error()	 (sending an error response)
44  *   ns_client_drop() (sending no response, logging the reason)
45  *\endcode
46  * This will release any resources used by the request and
47  * and allow the ns_client_t to listen for the next request.
48  *
49  * A ns_clientmgr_t manages a number of ns_client_t objects.
50  * New ns_client_t objects are created by calling
51  * ns_clientmgr_createclients(). They are destroyed by
52  * destroying their manager.
53  */
54 
55 /***
56  *** Imports
57  ***/
58 
59 #include <inttypes.h>
60 #include <stdbool.h>
61 
62 #include <isc/atomic.h>
63 #include <isc/buffer.h>
64 #include <isc/magic.h>
65 #include <isc/netmgr.h>
66 #include <isc/platform.h>
67 #include <isc/quota.h>
68 #include <isc/stdtime.h>
69 
70 #include <dns/db.h>
71 #include <dns/ecs.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 <ns/query.h>
80 #include <ns/types.h>
81 
82 /***
83  *** Types
84  ***/
85 
86 #define NS_CLIENT_TCP_BUFFER_SIZE  65535
87 #define NS_CLIENT_SEND_BUFFER_SIZE 4096
88 
89 /*!
90  * Client object states.  Ordering is significant: higher-numbered
91  * states are generally "more active", meaning that the client can
92  * have more dynamically allocated data, outstanding events, etc.
93  * In the list below, any such properties listed for state N
94  * also apply to any state > N.
95  */
96 
97 typedef enum {
98 	NS_CLIENTSTATE_FREED = 0,
99 	/*%<
100 	 * The client object no longer exists.
101 	 */
102 
103 	NS_CLIENTSTATE_INACTIVE = 1,
104 	/*%<
105 	 * The client object exists and has a task and timer.
106 	 * Its "query" struct and sendbuf are initialized.
107 	 * It has a message and OPT, both in the reset state.
108 	 */
109 
110 	NS_CLIENTSTATE_READY = 2,
111 	/*%<
112 	 * The client object is either a TCP or a UDP one, and
113 	 * it is associated with a network interface.  It is on the
114 	 * client manager's list of active clients.
115 	 *
116 	 * If it is a TCP client object, it has a TCP listener socket
117 	 * and an outstanding TCP listen request.
118 	 *
119 	 * If it is a UDP client object, it has a UDP listener socket
120 	 * and an outstanding UDP receive request.
121 	 */
122 
123 	NS_CLIENTSTATE_WORKING = 3,
124 	/*%<
125 	 * The client object has received a request and is working
126 	 * on it.  It has a view, and it may have any of a non-reset OPT,
127 	 * recursion quota, and an outstanding write request.
128 	 */
129 
130 	NS_CLIENTSTATE_RECURSING = 4,
131 	/*%<
132 	 * The client object is recursing.  It will be on the
133 	 * 'recursing' list.
134 	 */
135 
136 	NS_CLIENTSTATE_MAX = 5
137 	/*%<
138 	 * Sentinel value used to indicate "no state".
139 	 */
140 } ns_clientstate_t;
141 
142 typedef ISC_LIST(ns_client_t) client_list_t;
143 
144 /*% nameserver client manager structure */
145 struct ns_clientmgr {
146 	/* Unlocked. */
147 	unsigned int magic;
148 
149 	isc_mem_t	  *mctx;
150 	ns_server_t    *sctx;
151 	isc_taskmgr_t  *taskmgr;
152 	isc_timermgr_t *timermgr;
153 	isc_task_t	   *excl;
154 	isc_refcount_t	references;
155 	int		ncpus;
156 
157 	/* Attached by clients, needed for e.g. recursion */
158 	isc_task_t **taskpool;
159 
160 	ns_interface_t *interface;
161 
162 	/* Lock covers manager state. */
163 	isc_mutex_t lock;
164 	bool	    exiting;
165 
166 	/* Lock covers the recursing list */
167 	isc_mutex_t   reclock;
168 	client_list_t recursing; /*%< Recursing clients */
169 
170 	/*%< mctx pool for clients. */
171 	isc_mem_t **mctxpool;
172 };
173 
174 /*% nameserver client structure */
175 struct ns_client {
176 	unsigned int	 magic;
177 	isc_mem_t	  *mctx;
178 	bool		 allocated; /* Do we need to free it? */
179 	ns_server_t	    *sctx;
180 	ns_clientmgr_t  *manager;
181 	ns_clientstate_t state;
182 	int		 nupdates;
183 	bool		 nodetach;
184 	bool		 shuttingdown;
185 	unsigned int	 attributes;
186 	isc_task_t	   *task;
187 	dns_view_t	   *view;
188 	dns_dispatch_t  *dispatch;
189 	isc_nmhandle_t  *handle;	/* Permanent pointer to handle */
190 	isc_nmhandle_t  *sendhandle;	/* Waiting for send callback */
191 	isc_nmhandle_t  *reqhandle;	/* Waiting for request callback
192 					   (query, update, notify) */
193 	isc_nmhandle_t *fetchhandle;	/* Waiting for recursive fetch */
194 	isc_nmhandle_t *prefetchhandle; /* Waiting for prefetch / rpzfetch */
195 	isc_nmhandle_t *updatehandle;	/* Waiting for update callback */
196 	unsigned char  *tcpbuf;
197 	dns_message_t  *message;
198 	unsigned char  *sendbuf;
199 	dns_rdataset_t *opt;
200 	uint16_t	udpsize;
201 	uint16_t	extflags;
202 	int16_t		ednsversion; /* -1 noedns */
203 	void (*cleanup)(ns_client_t *);
204 	ns_query_t    query;
205 	isc_time_t    requesttime;
206 	isc_stdtime_t now;
207 	isc_time_t    tnow;
208 	dns_name_t    signername; /*%< [T]SIG key name */
209 	dns_name_t   *signer;	  /*%< NULL if not valid sig */
210 	bool	      mortal;	  /*%< Die after handling request */
211 	isc_quota_t  *recursionquota;
212 
213 	isc_sockaddr_t peeraddr;
214 	bool	       peeraddr_valid;
215 	isc_netaddr_t  destaddr;
216 	isc_sockaddr_t destsockaddr;
217 
218 	dns_ecs_t ecs; /*%< EDNS client subnet sent by client */
219 
220 	struct in6_pktinfo pktinfo;
221 	isc_dscp_t	   dscp;
222 	/*%
223 	 * Information about recent FORMERR response(s), for
224 	 * FORMERR loop avoidance.  This is separate for each
225 	 * client object rather than global only to avoid
226 	 * the need for locking.
227 	 */
228 	struct {
229 		isc_sockaddr_t	addr;
230 		isc_stdtime_t	time;
231 		dns_messageid_t id;
232 	} formerrcache;
233 
234 	/*% Callback function to send a response when unit testing */
235 	void (*sendcb)(isc_buffer_t *buf);
236 
237 	ISC_LINK(ns_client_t) rlink;
238 	unsigned char  cookie[8];
239 	uint32_t       expire;
240 	unsigned char *keytag;
241 	uint16_t       keytag_len;
242 
243 	/*%
244 	 * Used to override the DNS response code in ns_client_error().
245 	 * If set to -1, the rcode is determined from the result code,
246 	 * but if set to any other value, the least significant 12
247 	 * bits will be used as the rcode in the response message.
248 	 */
249 	int32_t rcode_override;
250 };
251 
252 #define NS_CLIENT_MAGIC	   ISC_MAGIC('N', 'S', 'C', 'c')
253 #define NS_CLIENT_VALID(c) ISC_MAGIC_VALID(c, NS_CLIENT_MAGIC)
254 
255 #define NS_CLIENTATTR_TCP	 0x00001
256 #define NS_CLIENTATTR_RA	 0x00002 /*%< Client gets recursive service */
257 #define NS_CLIENTATTR_PKTINFO	 0x00004 /*%< pktinfo is valid */
258 #define NS_CLIENTATTR_MULTICAST	 0x00008 /*%< recv'd from multicast */
259 #define NS_CLIENTATTR_WANTDNSSEC 0x00010 /*%< include dnssec records */
260 #define NS_CLIENTATTR_WANTNSID	 0x00020 /*%< include nameserver ID */
261 /* Obsolete: NS_CLIENTATTR_FILTER_AAAA	0x00040 */
262 /* Obsolete: NS_CLIENTATTR_FILTER_AAAA_RC 0x00080 */
263 #define NS_CLIENTATTR_WANTAD	   0x00100 /*%< want AD in response if possible */
264 #define NS_CLIENTATTR_WANTCOOKIE   0x00200 /*%< return a COOKIE */
265 #define NS_CLIENTATTR_HAVECOOKIE   0x00400 /*%< has a valid COOKIE */
266 #define NS_CLIENTATTR_WANTEXPIRE   0x00800 /*%< return seconds to expire */
267 #define NS_CLIENTATTR_HAVEEXPIRE   0x01000 /*%< return seconds to expire */
268 #define NS_CLIENTATTR_WANTOPT	   0x02000 /*%< add opt to reply */
269 #define NS_CLIENTATTR_HAVEECS	   0x04000 /*%< received an ECS option */
270 #define NS_CLIENTATTR_WANTPAD	   0x08000 /*%< pad reply */
271 #define NS_CLIENTATTR_USEKEEPALIVE 0x10000 /*%< use TCP keepalive */
272 
273 #define NS_CLIENTATTR_NOSETFC 0x20000 /*%< don't set servfail cache */
274 
275 /*
276  * Flag to use with the SERVFAIL cache to indicate
277  * that a query had the CD bit set.
278  */
279 #define NS_FAILCACHE_CD 0x01
280 
281 #if defined(_WIN32) && !defined(_WIN64)
282 LIBNS_EXTERNAL_DATA extern atomic_uint_fast32_t ns_client_requests;
283 #else  /* if defined(_WIN32) && !defined(_WIN64) */
284 LIBNS_EXTERNAL_DATA extern atomic_uint_fast64_t ns_client_requests;
285 #endif /* if defined(_WIN32) && !defined(_WIN64) */
286 
287 /***
288  *** Functions
289  ***/
290 
291 /*
292  * Note!  These ns_client_ routines MUST be called ONLY from the client's
293  * task in order to ensure synchronization.
294  */
295 
296 void
297 ns_client_send(ns_client_t *client);
298 /*%<
299  * Finish processing the current client request and
300  * send client->message as a response.
301  * \brief
302  * Note!  These ns_client_ routines MUST be called ONLY from the client's
303  * task in order to ensure synchronization.
304  */
305 
306 void
307 ns_client_sendraw(ns_client_t *client, dns_message_t *msg);
308 /*%<
309  * Finish processing the current client request and
310  * send msg as a response using client->message->id for the id.
311  */
312 
313 void
314 ns_client_error(ns_client_t *client, isc_result_t result);
315 /*%<
316  * Finish processing the current client request and return
317  * an error response to the client.  The error response
318  * will have an RCODE determined by 'result'.
319  */
320 
321 void
322 ns_client_drop(ns_client_t *client, isc_result_t result);
323 /*%<
324  * Log the reason the current client request has failed; no response
325  * will be sent.
326  */
327 
328 bool
329 ns_client_shuttingdown(ns_client_t *client);
330 /*%<
331  * Return true iff the client is currently shutting down.
332  */
333 
334 isc_result_t
335 ns_client_replace(ns_client_t *client);
336 /*%<
337  * Try to replace the current client with a new one, so that the
338  * current one can go off and do some lengthy work without
339  * leaving the dispatch/socket without service.
340  */
341 
342 void
343 ns_client_settimeout(ns_client_t *client, unsigned int seconds);
344 /*%<
345  * Set a timer in the client to go off in the specified amount of time.
346  */
347 
348 isc_result_t
349 ns_clientmgr_create(isc_mem_t *mctx, ns_server_t *sctx, isc_taskmgr_t *taskmgr,
350 		    isc_timermgr_t *timermgr, ns_interface_t *ifp, int ncpus,
351 		    ns_clientmgr_t **managerp);
352 /*%<
353  * Create a client manager.
354  */
355 
356 void
357 ns_clientmgr_destroy(ns_clientmgr_t **managerp);
358 /*%<
359  * Destroy a client manager and all ns_client_t objects
360  * managed by it.
361  */
362 
363 isc_sockaddr_t *
364 ns_client_getsockaddr(ns_client_t *client);
365 /*%<
366  * Get the socket address of the client whose request is
367  * currently being processed.
368  */
369 
370 isc_sockaddr_t *
371 ns_client_getdestaddr(ns_client_t *client);
372 /*%<
373  * Get the destination address (server) for the request that is
374  * currently being processed.
375  */
376 
377 isc_result_t
378 ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
379 			 dns_acl_t *acl, bool default_allow);
380 
381 /*%<
382  * Convenience function for client request ACL checking.
383  *
384  * Check the current client request against 'acl'.  If 'acl'
385  * is NULL, allow the request iff 'default_allow' is true.
386  * If netaddr is NULL, check the ACL against client->peeraddr;
387  * otherwise check it against netaddr.
388  *
389  * Notes:
390  *\li	This is appropriate for checking allow-update,
391  * 	allow-query, allow-transfer, etc.  It is not appropriate
392  * 	for checking the blackhole list because we treat positive
393  * 	matches as "allow" and negative matches as "deny"; in
394  *	the case of the blackhole list this would be backwards.
395  *
396  * Requires:
397  *\li	'client' points to a valid client.
398  *\li	'netaddr' points to a valid address, or is NULL.
399  *\li	'acl' points to a valid ACL, or is NULL.
400  *
401  * Returns:
402  *\li	ISC_R_SUCCESS	if the request should be allowed
403  * \li	DNS_R_REFUSED	if the request should be denied
404  *\li	No other return values are possible.
405  */
406 
407 isc_result_t
408 ns_client_checkacl(ns_client_t *client, isc_sockaddr_t *sockaddr,
409 		   const char *opname, dns_acl_t *acl, bool default_allow,
410 		   int log_level);
411 /*%<
412  * Like ns_client_checkaclsilent, except the outcome of the check is
413  * logged at log level 'log_level' if denied, and at debug 3 if approved.
414  * Log messages will refer to the request as an 'opname' request.
415  *
416  * Requires:
417  *\li	'client' points to a valid client.
418  *\li	'sockaddr' points to a valid address, or is NULL.
419  *\li	'acl' points to a valid ACL, or is NULL.
420  *\li	'opname' points to a null-terminated string.
421  */
422 
423 void
424 ns_client_log(ns_client_t *client, isc_logcategory_t *category,
425 	      isc_logmodule_t *module, int level, const char *fmt, ...)
426 	ISC_FORMAT_PRINTF(5, 6);
427 
428 void
429 ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
430 	       isc_logmodule_t *module, int level, const char *fmt, va_list ap)
431 	ISC_FORMAT_PRINTF(5, 0);
432 
433 void
434 ns_client_aclmsg(const char *msg, const dns_name_t *name, dns_rdatatype_t type,
435 		 dns_rdataclass_t rdclass, char *buf, size_t len);
436 
437 #define NS_CLIENT_ACLMSGSIZE(x)                           \
438 	(DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + \
439 	 DNS_RDATACLASS_FORMATSIZE + sizeof(x) + sizeof("'/'"))
440 
441 void
442 ns_client_recursing(ns_client_t *client);
443 /*%<
444  * Add client to end of th recursing list.
445  */
446 
447 void
448 ns_client_killoldestquery(ns_client_t *client);
449 /*%<
450  * Kill the oldest recursive query (recursing list head).
451  */
452 
453 void
454 ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager);
455 /*%<
456  * Dump the outstanding recursive queries to 'f'.
457  */
458 
459 void
460 ns_client_qnamereplace(ns_client_t *client, dns_name_t *name);
461 /*%<
462  * Replace the qname.
463  */
464 
465 isc_result_t
466 ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp);
467 
468 isc_result_t
469 ns_client_addopt(ns_client_t *client, dns_message_t *message,
470 		 dns_rdataset_t **opt);
471 
472 /*%<
473  * Get a client object from the inactive queue, or create one, as needed.
474  * (Not intended for use outside this module and associated tests.)
475  */
476 
477 void
478 ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
479 		   isc_region_t *region, void *arg);
480 
481 /*%<
482  * Handle client requests.
483  * (Not intended for use outside this module and associated tests.)
484  */
485 
486 isc_result_t
487 ns__client_tcpconn(isc_nmhandle_t *handle, isc_result_t result, void *arg);
488 
489 /*%<
490  * Called every time a TCP connection is establish.  This is used for
491  * updating TCP statistics.
492  */
493 
494 dns_rdataset_t *
495 ns_client_newrdataset(ns_client_t *client);
496 
497 void
498 ns_client_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp);
499 /*%<
500  * Get and release temporary rdatasets in the client message;
501  * used in query.c and in plugins.
502  */
503 
504 isc_result_t
505 ns_client_newnamebuf(ns_client_t *client);
506 /*%<
507  * Allocate a name buffer for the client message.
508  */
509 
510 dns_name_t *
511 ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf);
512 /*%<
513  * Get a temporary name for the client message.
514  */
515 
516 isc_buffer_t *
517 ns_client_getnamebuf(ns_client_t *client);
518 /*%<
519  * Get a name buffer from the pool, or allocate a new one if needed.
520  */
521 
522 void
523 ns_client_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf);
524 /*%<
525  * Adjust buffer 'dbuf' to reflect that 'name' is using space in it,
526  * and set client attributes appropriately.
527  */
528 
529 void
530 ns_client_releasename(ns_client_t *client, dns_name_t **namep);
531 /*%<
532  * Release 'name' back to the pool of temporary names for the client
533  * message. If it is using a name buffer, relinquish its exclusive
534  * rights on the buffer.
535  */
536 
537 isc_result_t
538 ns_client_newdbversion(ns_client_t *client, unsigned int n);
539 /*%<
540  * Allocate 'n' new database versions for use by client queries.
541  */
542 
543 ns_dbversion_t *
544 ns_client_getdbversion(ns_client_t *client);
545 /*%<
546  * Get a free database version for use by a client query, allocating
547  * a new one if necessary.
548  */
549 
550 ns_dbversion_t *
551 ns_client_findversion(ns_client_t *client, dns_db_t *db);
552 /*%<
553  * Find the correct database version to use with a client query.
554  * If we have already done a query related to the database 'db',
555  * make sure subsequent queries are from the same version;
556  * otherwise, take a database version from the list of dbversions
557  * allocated by ns_client_newdbversion().
558  */
559 
560 isc_result_t
561 ns__client_setup(ns_client_t *client, ns_clientmgr_t *manager, bool new);
562 /*%<
563  * Perform initial setup of an allocated client.
564  */
565 
566 void
567 ns__client_reset_cb(void *client0);
568 /*%<
569  * Reset the client object so that it can be reused.
570  */
571 
572 void
573 ns__client_put_cb(void *client0);
574 /*%<
575  * Free all resources allocated to this client object, so that
576  * it can be freed.
577  */
578 
579 #endif /* NS_CLIENT_H */
580