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