xref: /netbsd-src/external/mpl/bind/dist/lib/dns/include/dns/client.h (revision bcda20f65a8566e103791ec395f7f499ef322704)
1 /*	$NetBSD: client.h,v 1.10 2025/01/26 16:25:26 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 #pragma once
17 
18 /*****
19 ***** Module Info
20 *****/
21 
22 /*! \file
23  *
24  * \brief
25  * The DNS client module provides convenient programming interfaces to various
26  * DNS services, such as name resolution with or without DNSSEC validation or
27  * dynamic DNS update.  This module is primarily expected to be used by other
28  * applications than BIND9-related ones that need such advanced DNS features.
29  *
30  * MP:
31  *\li	In the typical usage of this module, application threads will not share
32  *	the same data structures created and manipulated in this module.
33  *	However, the module still ensures appropriate synchronization of such
34  *	data structures.
35  *
36  * Resources:
37  *\li	TBS
38  *
39  * Security:
40  *\li	This module does not handle any low-level data directly, and so no
41  *	security issue specific to this module is anticipated.
42  */
43 
44 #include <isc/loop.h>
45 #include <isc/sockaddr.h>
46 #include <isc/tls.h>
47 
48 #include <dns/tsig.h>
49 #include <dns/types.h>
50 
51 #include <dst/dst.h>
52 
53 ISC_LANG_BEGINDECLS
54 
55 /***
56  *** Types
57  ***/
58 
59 /*%
60  * Optional flags for dns_client_resolve.
61  */
62 /*%< Do not return DNSSEC data (e.g. RRSIGS) with response. */
63 #define DNS_CLIENTRESOPT_NODNSSEC 0x01
64 /*%< Allow running external context. */
65 #define DNS_CLIENTRESOPT_RESERVED 0x02
66 /*%< Don't validate responses. */
67 #define DNS_CLIENTRESOPT_NOVALIDATE 0x04
68 /*%< Don't set the CD flag on upstream queries. */
69 #define DNS_CLIENTRESOPT_NOCDFLAG 0x08
70 /*%< Use TCP transport. */
71 #define DNS_CLIENTRESOPT_TCP 0x10
72 
73 /*%
74  * View name used in dns_client.
75  */
76 #define DNS_CLIENTVIEW_NAME "_dnsclient"
77 
78 /*%
79  * A dns_clientresume_t holds state for resolution performed by a client,
80  * and is sent to the callback when the resolution completes.
81  * 'result' stores the result code of the entire resolution
82  * procedure.  'vresult' specifically stores the result code of DNSSEC
83  * validation if it is performed.  When name resolution successfully completes,
84  * 'answerlist' is typically non empty, containing answer names along with
85  * RRsets. 'cb' is the callback function and 'arg' is the callback argument
86  * that was specified by the caller.
87  *
88  * It is the receiver's responsibility to free 'answerlist' by
89  * calling dns_client_freeresanswer(), and to free the dns_clientresume
90  * structure itself.
91  */
92 typedef struct dns_clientresume {
93 	isc_mem_t     *mctx;
94 	isc_result_t   result;
95 	isc_result_t   vresult;
96 	dns_namelist_t answerlist;
97 	isc_job_cb     cb;
98 	void	      *arg;
99 } dns_clientresume_t; /* too long? */
100 
101 isc_result_t
102 dns_client_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr, isc_nm_t *nm,
103 		  unsigned int options, isc_tlsctx_cache_t *tlsctx_client_cache,
104 		  dns_client_t **clientp, const isc_sockaddr_t *localaddr4,
105 		  const isc_sockaddr_t *localaddr6);
106 /*%<
107  * Create a DNS client object with minimal internal resources, such as
108  * a default view for the IN class and IPv4/IPv6 dispatches for the view.
109  *
110  * dns_client_create() takes 'manager' arguments so that the caller can
111  * control the behavior of the client through the underlying event framework.
112  * 'localaddr4' and 'localaddr6' specify the local addresses to use for
113  * each address family; if both are set to NULL, then wildcard addresses
114  * will be used for both families. If only one is NULL, then the other
115  * address will be used as the local address, and the NULL protocol family
116  * will not be used.
117  *
118  * Requires:
119  *
120  *\li	'mctx' is a valid memory context.
121  *
122  *\li	'loopmgr' is a valid loop manager.
123 
124  *\li	'nm' is a valid network manager.
125  *
126  *\li	'tlsctx_client_cache' is a valid TLS context cache.
127  *
128  *\li	clientp != NULL && *clientp == NULL.
129  *
130  * Returns:
131  *
132  *\li	#ISC_R_SUCCESS				On success.
133  *
134  *\li	Anything else				Failure.
135  */
136 
137 void
138 dns_client_detach(dns_client_t **clientp);
139 /*%<
140  * Detach 'client' and destroy it if there are no more references.
141  *
142  * Requires:
143  *
144  *\li	'*clientp' is a valid client.
145  *
146  * Ensures:
147  *
148  *\li	*clientp == NULL.
149  */
150 
151 isc_result_t
152 dns_client_setservers(dns_client_t *client, dns_rdataclass_t rdclass,
153 		      const dns_name_t *name_space, isc_sockaddrlist_t *addrs);
154 /*%<
155  * Specify a list of addresses of recursive name servers that the client will
156  * use for name resolution.  A view for the 'rdclass' class must be created
157  * beforehand.  If 'name_space' is non NULL, the specified server will be used
158  * if and only if the query name is a subdomain of 'name_space'.  When servers
159  * for multiple 'name_space's are provided, and a query name is covered by
160  * more than one 'name_space', the servers for the best (longest) matching
161  * name_space will be used.  If 'name_space' is NULL, it works as if
162  * dns_rootname (.) were specified.
163  *
164  * Requires:
165  *
166  *\li	'client' is a valid client.
167  *
168  *\li	'name_space' is NULL or a valid name.
169  *
170  *\li	'addrs' != NULL.
171  *
172  * Returns:
173  *
174  *\li	#ISC_R_SUCCESS				On success.
175  *
176  *\li	Anything else				Failure.
177  */
178 
179 void
180 dns_client_setmaxrestarts(dns_client_t *client, uint8_t max_restarts);
181 /*%<
182  * Set the number of permissible chained queries before we give up,
183  * to prevent CNAME loops. This defaults to 11.
184  *
185  * Requires:
186  *
187  *\li	'client' is a valid client.
188 
189  *\li	'max_restarts' is greater than 0.
190  */
191 
192 typedef void (*dns_client_resolve_cb)(dns_client_t     *client,
193 				      const dns_name_t *name,
194 				      dns_namelist_t   *namelist,
195 				      isc_result_t	result);
196 
197 isc_result_t
198 dns_client_resolve(dns_client_t *client, const dns_name_t *name,
199 		   dns_rdataclass_t rdclass, dns_rdatatype_t type,
200 		   unsigned int options, dns_namelist_t *namelist,
201 		   dns_client_resolve_cb resolve_cb);
202 
203 /*%<
204  * Perform name resolution for 'name', 'rdclass', and 'type'.
205  *
206  * If any trusted keys are configured and the query name is considered to
207  * belong to a secure zone, these functions also validate the responses
208  * using DNSSEC by default.  If the DNS_CLIENTRESOPT_NOVALIDATE flag is set
209  * in 'options', DNSSEC validation is disabled regardless of the configured
210  * trusted keys or the query name. With DNS_CLIENTRESOPT_NODNSSEC
211  * DNSSEC data is not returned with response. DNS_CLIENTRESOPT_NOCDFLAG
212  * disables the CD flag on queries, DNS_CLIENTRESOPT_TCP switches to
213  * the TCP (vs. UDP) transport.
214  *
215  * dns_client_resolve() provides a synchronous service.  This function starts
216  * name resolution internally and blocks until it completes.  On success,
217  * 'namelist' will contain a list of answer names, each of which has
218  * corresponding RRsets.  The caller must provide a valid empty list, and
219  * is responsible for freeing the list content via dns_client_freeresanswer().
220  * If the name resolution fails due to an error in DNSSEC validation,
221  * dns_client_resolve() returns the result code indicating the validation
222  * error. Otherwise, it returns the result code of the entire resolution
223  * process, either success or failure.
224  *
225  * It is expected that the client object passed to dns_client_resolve() was
226  * created via dns_client_create() and has external managers and contexts.
227  *
228  * Requires:
229  *
230  *\li	'client' is a valid client.
231  *
232  *\li	'addrs' != NULL.
233  *
234  *\li	'name' is a valid name.
235  *
236  *\li	'namelist' != NULL and is not empty.
237  *
238  *\li	'transp' != NULL && *transp == NULL;
239  *
240  * Returns:
241  *
242  *\li	#ISC_R_SUCCESS				On success.
243  *
244  *\li	Anything else				Failure.
245  */
246 
247 void
248 dns_client_freeresanswer(dns_client_t *client, dns_namelist_t *namelist);
249 /*%<
250  * Free resources allocated for the content of 'namelist'.
251  *
252  * Requires:
253  *
254  *\li	'client' is a valid client.
255  *
256  *\li	'namelist' != NULL.
257  */
258 
259 isc_result_t
260 dns_client_addtrustedkey(dns_client_t *client, dns_rdataclass_t rdclass,
261 			 dns_rdatatype_t rdtype, const dns_name_t *keyname,
262 			 isc_buffer_t *keydatabuf);
263 /*%<
264  * Add a DNSSEC trusted key for the 'rdclass' class (only class 'IN' is
265  * currently supported).  A view for the 'rdclass' class must be created
266  * beforehand.  'rdtype' is the type of the RR data for the key, either
267  * DNSKEY or DS.  'keyname' is the DNS name of the key, and 'keydatabuf'
268  * stores the RR data.
269  *
270  * Requires:
271  *
272  *\li	'client' is a valid client.
273  *
274  *\li	'keyname' is a valid name.
275  *
276  *\li	'keydatabuf' is a valid buffer.
277  *
278  * Returns:
279  *
280  *\li	#ISC_R_SUCCESS				On success.
281  *
282  *\li	Anything else				Failure.
283  */
284 
285 ISC_LANG_ENDDECLS
286