1 /* 2 * Copyright (c) 2017-2021, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * @brief 32 * This file defines the top-level DNS functions for the OpenThread library. 33 */ 34 35 #ifndef OPENTHREAD_DNS_CLIENT_H_ 36 #define OPENTHREAD_DNS_CLIENT_H_ 37 38 #include <openthread/dns.h> 39 #include <openthread/instance.h> 40 #include <openthread/ip6.h> 41 42 #ifdef __cplusplus 43 extern "C" { 44 #endif 45 46 /** 47 * @addtogroup api-dns 48 * 49 * @brief 50 * This module includes functions that control DNS communication. 51 * 52 * The functions in this module are available only if feature `OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE` is enabled. 53 * 54 * @{ 55 */ 56 57 /** 58 * Type represents the "Recursion Desired" (RD) flag in an `otDnsQueryConfig`. 59 */ 60 typedef enum 61 { 62 OT_DNS_FLAG_UNSPECIFIED = 0, ///< Indicates the flag is not specified. 63 OT_DNS_FLAG_RECURSION_DESIRED = 1, ///< Indicates DNS name server can resolve the query recursively. 64 OT_DNS_FLAG_NO_RECURSION = 2, ///< Indicates DNS name server can not resolve the query recursively. 65 } otDnsRecursionFlag; 66 67 /** 68 * Type represents the NAT64 mode in an `otDnsQueryConfig`. 69 * 70 * The NAT64 mode indicates whether to allow or disallow NAT64 address translation during DNS client address resolution. 71 * This mode is only used when `OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE` is enabled. 72 */ 73 typedef enum 74 { 75 OT_DNS_NAT64_UNSPECIFIED = 0, ///< NAT64 mode is not specified. Use default NAT64 mode. 76 OT_DNS_NAT64_ALLOW = 1, ///< Allow NAT64 address translation during DNS client address resolution. 77 OT_DNS_NAT64_DISALLOW = 2, ///< Do not allow NAT64 address translation during DNS client address resolution. 78 } otDnsNat64Mode; 79 80 /** 81 * Type represents the service resolution mode in an `otDnsQueryConfig`. 82 * 83 * This is only used during DNS client service resolution `otDnsClientResolveService()`. It determines which 84 * record types to query. 85 */ 86 typedef enum 87 { 88 OT_DNS_SERVICE_MODE_UNSPECIFIED = 0, ///< Mode is not specified. Use default service mode. 89 OT_DNS_SERVICE_MODE_SRV = 1, ///< Query for SRV record only. 90 OT_DNS_SERVICE_MODE_TXT = 2, ///< Query for TXT record only. 91 OT_DNS_SERVICE_MODE_SRV_TXT = 3, ///< Query for both SRV and TXT records in same message. 92 OT_DNS_SERVICE_MODE_SRV_TXT_SEPARATE = 4, ///< Query in parallel for SRV and TXT using separate messages. 93 OT_DNS_SERVICE_MODE_SRV_TXT_OPTIMIZE = 5, ///< Query for TXT/SRV together first, if fails then query separately. 94 } otDnsServiceMode; 95 96 /** 97 * Type represents the DNS transport protocol in an `otDnsQueryConfig`. 98 * 99 * This `OT_DNS_TRANSPORT_TCP` is only supported when `OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_ENABLE` is enabled. 100 */ 101 typedef enum 102 { 103 OT_DNS_TRANSPORT_UNSPECIFIED = 0, /// DNS transport is unspecified. 104 OT_DNS_TRANSPORT_UDP = 1, /// DNS query should be sent via UDP. 105 OT_DNS_TRANSPORT_TCP = 2, /// DNS query should be sent via TCP. 106 } otDnsTransportProto; 107 108 /** 109 * Represents a DNS query configuration. 110 * 111 * Any of the fields in this structure can be set to zero to indicate that it is not specified. How the unspecified 112 * fields are treated is determined by the function which uses the instance of `otDnsQueryConfig`. 113 */ 114 typedef struct otDnsQueryConfig 115 { 116 otSockAddr mServerSockAddr; ///< Server address (IPv6 addr/port). All zero or zero port for unspecified. 117 uint32_t mResponseTimeout; ///< Wait time (in msec) to rx response. Zero indicates unspecified value. 118 uint8_t mMaxTxAttempts; ///< Maximum tx attempts before reporting failure. Zero for unspecified value. 119 otDnsRecursionFlag mRecursionFlag; ///< Indicates whether the server can resolve the query recursively or not. 120 otDnsNat64Mode mNat64Mode; ///< Allow/Disallow NAT64 address translation during address resolution. 121 otDnsServiceMode mServiceMode; ///< Determines which records to query during service resolution. 122 otDnsTransportProto mTransportProto; ///< Select default transport protocol. 123 } otDnsQueryConfig; 124 125 /** 126 * Gets the current default query config used by DNS client. 127 * 128 * When OpenThread stack starts, the default DNS query config is determined from a set of OT config options such as 129 * `OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_SERVER_IP6_ADDRESS`, `_DEFAULT_SERVER_PORT`, `_DEFAULT_RESPONSE_TIMEOUT`, etc. 130 * (see `config/dns_client.h` for all related config options). 131 * 132 * @param[in] aInstance A pointer to an OpenThread instance. 133 * 134 * @returns A pointer to the current default config being used by DNS client. 135 */ 136 const otDnsQueryConfig *otDnsClientGetDefaultConfig(otInstance *aInstance); 137 138 /** 139 * Sets the default query config on DNS client. 140 * 141 * @note Any ongoing query will continue to use the config from when it was started. The new default config will be 142 * used for any future DNS queries. 143 * 144 * The @p aConfig can be NULL. In this case the default config will be set to the defaults from OT config options 145 * `OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_{}`. This resets the default query config back to to the config when the 146 * OpenThread stack starts. 147 * 148 * In a non-NULL @p aConfig, caller can choose to leave some of the fields in `otDnsQueryConfig` instance unspecified 149 * (value zero). The unspecified fields are replaced by the corresponding OT config option definitions 150 * `OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_{}` to form the default query config. 151 * 152 * When `OPENTHREAD_CONFIG_DNS_CLIENT_DEFAULT_SERVER_ADDRESS_AUTO_SET_ENABLE` is enabled, the server's IPv6 address in 153 * the default config is automatically set and updated by DNS client. This is done only when user does not explicitly 154 * set or specify it. This behavior requires SRP client and its auto-start feature to be enabled. SRP client will then 155 * monitor the Thread Network Data for DNS/SRP Service entries to select an SRP server. The selected SRP server address 156 * is also set as the DNS server address in the default config. 157 * 158 * @param[in] aInstance A pointer to an OpenThread instance. 159 * @param[in] aConfig A pointer to the new query config to use as default. 160 */ 161 void otDnsClientSetDefaultConfig(otInstance *aInstance, const otDnsQueryConfig *aConfig); 162 163 /** 164 * An opaque representation of a response to an address resolution DNS query. 165 * 166 * Pointers to instance of this type are provided from callback `otDnsAddressCallback`. 167 */ 168 typedef struct otDnsAddressResponse otDnsAddressResponse; 169 170 /** 171 * Pointer is called when a DNS response is received for an address resolution query. 172 * 173 * Within this callback the user can use `otDnsAddressResponseGet{Item}()` functions along with the @p aResponse 174 * pointer to get more info about the response. 175 * 176 * The @p aResponse pointer can only be used within this callback and after returning from this function it will not 177 * stay valid, so the user MUST NOT retain the @p aResponse pointer for later use. 178 * 179 * @param[in] aError The result of the DNS transaction. 180 * @param[in] aResponse A pointer to the response (it is always non-NULL). 181 * @param[in] aContext A pointer to application-specific context. 182 * 183 * The @p aError can have the following: 184 * 185 * - OT_ERROR_NONE A response was received successfully. 186 * - OT_ERROR_ABORT A DNS transaction was aborted by stack. 187 * - OT_ERROR_RESPONSE_TIMEOUT No DNS response has been received within timeout. 188 * 189 * If the server rejects the address resolution request the error code from server is mapped as follow: 190 * 191 * - (0) NOERROR Success (no error condition) -> OT_ERROR_NONE 192 * - (1) FORMERR Server unable to interpret due to format error -> OT_ERROR_PARSE 193 * - (2) SERVFAIL Server encountered an internal failure -> OT_ERROR_FAILED 194 * - (3) NXDOMAIN Name that ought to exist, does not exist -> OT_ERROR_NOT_FOUND 195 * - (4) NOTIMP Server does not support the query type (OpCode) -> OT_ERROR_NOT_IMPLEMENTED 196 * - (5) REFUSED Server refused for policy/security reasons -> OT_ERROR_SECURITY 197 * - (6) YXDOMAIN Some name that ought not to exist, does exist -> OT_ERROR_DUPLICATED 198 * - (7) YXRRSET Some RRset that ought not to exist, does exist -> OT_ERROR_DUPLICATED 199 * - (8) NXRRSET Some RRset that ought to exist, does not exist -> OT_ERROR_NOT_FOUND 200 * - (9) NOTAUTH Service is not authoritative for zone -> OT_ERROR_SECURITY 201 * - (10) NOTZONE A name is not in the zone -> OT_ERROR_PARSE 202 * - (20) BADNAME Bad name -> OT_ERROR_PARSE 203 * - (21) BADALG Bad algorithm -> OT_ERROR_SECURITY 204 * - (22) BADTRUN Bad truncation -> OT_ERROR_PARSE 205 * - Other response codes -> OT_ERROR_FAILED 206 */ 207 typedef void (*otDnsAddressCallback)(otError aError, const otDnsAddressResponse *aResponse, void *aContext); 208 209 /** 210 * Sends an address resolution DNS query for AAAA (IPv6) record(s) for a given host name. 211 * 212 * The @p aConfig can be NULL. In this case the default config (from `otDnsClientGetDefaultConfig()`) will be used as 213 * the config for this query. In a non-NULL @p aConfig, some of the fields can be left unspecified (value zero). The 214 * unspecified fields are then replaced by the values from the default config. 215 * 216 * @param[in] aInstance A pointer to an OpenThread instance. 217 * @param[in] aHostName The host name for which to query the address (MUST NOT be NULL). 218 * @param[in] aCallback A function pointer that shall be called on response reception or time-out. 219 * @param[in] aContext A pointer to arbitrary context information. 220 * @param[in] aConfig A pointer to the config to use for this query. 221 * 222 * @retval OT_ERROR_NONE Query sent successfully. @p aCallback will be invoked to report the status. 223 * @retval OT_ERROR_NO_BUFS Insufficient buffer to prepare and send query. 224 * @retval OT_ERROR_INVALID_ARGS The host name is not valid format. 225 * @retval OT_ERROR_INVALID_STATE Cannot send query since Thread interface is not up. 226 */ 227 otError otDnsClientResolveAddress(otInstance *aInstance, 228 const char *aHostName, 229 otDnsAddressCallback aCallback, 230 void *aContext, 231 const otDnsQueryConfig *aConfig); 232 233 /** 234 * Sends an address resolution DNS query for A (IPv4) record(s) for a given host name. 235 * 236 * Requires and is available when `OPENTHREAD_CONFIG_DNS_CLIENT_NAT64_ENABLE` is enabled. 237 * 238 * When a successful response is received, the addresses are returned from @p aCallback as NAT64 IPv6 translated 239 * versions of the IPv4 addresses from the query response. 240 * 241 * The @p aConfig can be NULL. In this case the default config (from `otDnsClientGetDefaultConfig()`) will be used as 242 * the config for this query. In a non-NULL @p aConfig, some of the fields can be left unspecified (value zero). The 243 * unspecified fields are then replaced by the values from the default config. 244 * 245 * @param[in] aInstance A pointer to an OpenThread instance. 246 * @param[in] aHostName The host name for which to query the address (MUST NOT be NULL). 247 * @param[in] aCallback A function pointer that shall be called on response reception or time-out. 248 * @param[in] aContext A pointer to arbitrary context information. 249 * @param[in] aConfig A pointer to the config to use for this query. 250 * 251 * @retval OT_ERROR_NONE Query sent successfully. @p aCallback will be invoked to report the status. 252 * @retval OT_ERROR_NO_BUFS Insufficient buffer to prepare and send query. 253 * @retval OT_ERROR_INVALID_ARGS The host name is not valid format or NAT64 is not enabled in config. 254 * @retval OT_ERROR_INVALID_STATE Cannot send query since Thread interface is not up. 255 */ 256 otError otDnsClientResolveIp4Address(otInstance *aInstance, 257 const char *aHostName, 258 otDnsAddressCallback aCallback, 259 void *aContext, 260 const otDnsQueryConfig *aConfig); 261 262 /** 263 * Gets the full host name associated with an address resolution DNS response. 264 * 265 * MUST only be used from `otDnsAddressCallback`. 266 * 267 * @param[in] aResponse A pointer to the response. 268 * @param[out] aNameBuffer A buffer to char array to output the full host name (MUST NOT be NULL). 269 * @param[in] aNameBufferSize The size of @p aNameBuffer. 270 * 271 * @retval OT_ERROR_NONE The full host name was read successfully. 272 * @retval OT_ERROR_NO_BUFS The name does not fit in @p aNameBuffer. 273 */ 274 otError otDnsAddressResponseGetHostName(const otDnsAddressResponse *aResponse, 275 char *aNameBuffer, 276 uint16_t aNameBufferSize); 277 278 /** 279 * Gets an IPv6 address associated with an address resolution DNS response. 280 * 281 * MUST only be used from `otDnsAddressCallback`. 282 * 283 * The response may include multiple IPv6 address records. @p aIndex can be used to iterate through the list of 284 * addresses. Index zero gets the first address and so on. When we reach end of the list, `OT_ERROR_NOT_FOUND` is 285 * returned. 286 * 287 * @param[in] aResponse A pointer to the response. 288 * @param[in] aIndex The address record index to retrieve. 289 * @param[out] aAddress A pointer to a IPv6 address to output the address (MUST NOT be NULL). 290 * @param[out] aTtl A pointer to an `uint32_t` to output TTL for the address. It can be NULL if caller does not 291 * want to get the TTL. 292 * 293 * @retval OT_ERROR_NONE The address was read successfully. 294 * @retval OT_ERROR_NOT_FOUND No address record in @p aResponse at @p aIndex. 295 * @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse. 296 * @retval OT_ERROR_INVALID_STATE No NAT64 prefix (applicable only when NAT64 is allowed). 297 */ 298 otError otDnsAddressResponseGetAddress(const otDnsAddressResponse *aResponse, 299 uint16_t aIndex, 300 otIp6Address *aAddress, 301 uint32_t *aTtl); 302 303 /** 304 * An opaque representation of a response to a browse (service instance enumeration) DNS query. 305 * 306 * Pointers to instance of this type are provided from callback `otDnsBrowseCallback`. 307 */ 308 typedef struct otDnsBrowseResponse otDnsBrowseResponse; 309 310 /** 311 * Pointer is called when a DNS response is received for a browse (service instance enumeration) query. 312 * 313 * Within this callback the user can use `otDnsBrowseResponseGet{Item}()` functions along with the @p aResponse 314 * pointer to get more info about the response. 315 * 316 * The @p aResponse pointer can only be used within this callback and after returning from this function it will not 317 * stay valid, so the user MUST NOT retain the @p aResponse pointer for later use. 318 * 319 * @param[in] aError The result of the DNS transaction. 320 * @param[in] aResponse A pointer to the response (it is always non-NULL). 321 * @param[in] aContext A pointer to application-specific context. 322 * 323 * For the full list of possible values for @p aError, please see `otDnsAddressCallback()`. 324 */ 325 typedef void (*otDnsBrowseCallback)(otError aError, const otDnsBrowseResponse *aResponse, void *aContext); 326 327 /** 328 * Provides info for a DNS service instance. 329 */ 330 typedef struct otDnsServiceInfo 331 { 332 uint32_t mTtl; ///< Service record TTL (in seconds). 333 uint16_t mPort; ///< Service port number. 334 uint16_t mPriority; ///< Service priority. 335 uint16_t mWeight; ///< Service weight. 336 char *mHostNameBuffer; ///< Buffer to output the service host name (can be NULL if not needed). 337 uint16_t mHostNameBufferSize; ///< Size of `mHostNameBuffer`. 338 otIp6Address mHostAddress; ///< The host IPv6 address. Set to all zero if not available. 339 uint32_t mHostAddressTtl; ///< The host address TTL. 340 uint8_t *mTxtData; ///< Buffer to output TXT data (can be NULL if not needed). 341 uint16_t mTxtDataSize; ///< On input, size of `mTxtData` buffer. On output number bytes written. 342 bool mTxtDataTruncated; ///< Indicates if TXT data could not fit in `mTxtDataSize` and was truncated. 343 uint32_t mTxtDataTtl; ///< The TXT data TTL. 344 } otDnsServiceInfo; 345 346 /** 347 * Sends a DNS browse (service instance enumeration) query for a given service name. 348 * 349 * Is available when `OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE` is enabled. 350 * 351 * The @p aConfig can be NULL. In this case the default config (from `otDnsClientGetDefaultConfig()`) will be used as 352 * the config for this query. In a non-NULL @p aConfig, some of the fields can be left unspecified (value zero). The 353 * unspecified fields are then replaced by the values from the default config. 354 * 355 * @param[in] aInstance A pointer to an OpenThread instance. 356 * @param[in] aServiceName The service name to query for (MUST NOT be NULL). 357 * @param[in] aCallback A function pointer that shall be called on response reception or time-out. 358 * @param[in] aContext A pointer to arbitrary context information. 359 * @param[in] aConfig A pointer to the config to use for this query. 360 * 361 * @retval OT_ERROR_NONE Query sent successfully. @p aCallback will be invoked to report the status. 362 * @retval OT_ERROR_NO_BUFS Insufficient buffer to prepare and send query. 363 */ 364 otError otDnsClientBrowse(otInstance *aInstance, 365 const char *aServiceName, 366 otDnsBrowseCallback aCallback, 367 void *aContext, 368 const otDnsQueryConfig *aConfig); 369 370 /** 371 * Gets the service name associated with a DNS browse (service instance enumeration) response. 372 * 373 * MUST only be used from `otDnsBrowseCallback`. 374 * 375 * @param[in] aResponse A pointer to the response. 376 * @param[out] aNameBuffer A buffer to char array to output the service name (MUST NOT be NULL). 377 * @param[in] aNameBufferSize The size of @p aNameBuffer. 378 * 379 * @retval OT_ERROR_NONE The service name was read successfully. 380 * @retval OT_ERROR_NO_BUFS The name does not fit in @p aNameBuffer. 381 */ 382 otError otDnsBrowseResponseGetServiceName(const otDnsBrowseResponse *aResponse, 383 char *aNameBuffer, 384 uint16_t aNameBufferSize); 385 386 /** 387 * Gets a service instance associated with a DNS browse (service instance enumeration) response. 388 * 389 * MUST only be used from `otDnsBrowseCallback`. 390 * 391 * The response may include multiple service instance records. @p aIndex can be used to iterate through the list. Index 392 * zero gives the first record. When we reach end of the list, `OT_ERROR_NOT_FOUND` is returned. 393 * 394 * Note that this function gets the service instance label and not the full service instance name which is of the form 395 * `<Instance>.<Service>.<Domain>`. 396 * 397 * @param[in] aResponse A pointer to the response. 398 * @param[in] aIndex The service instance record index to retrieve. 399 * @param[out] aLabelBuffer A buffer to char array to output the service instance label (MUST NOT be NULL). 400 * @param[in] aLabelBufferSize The size of @p aLabelBuffer. 401 * 402 * @retval OT_ERROR_NONE The service instance was read successfully. 403 * @retval OT_ERROR_NO_BUFS The name does not fit in @p aNameBuffer. 404 * @retval OT_ERROR_NOT_FOUND No service instance record in @p aResponse at @p aIndex. 405 * @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse. 406 */ 407 otError otDnsBrowseResponseGetServiceInstance(const otDnsBrowseResponse *aResponse, 408 uint16_t aIndex, 409 char *aLabelBuffer, 410 uint8_t aLabelBufferSize); 411 412 /** 413 * Gets info for a service instance from a DNS browse (service instance enumeration) response. 414 * 415 * MUST only be used from `otDnsBrowseCallback`. 416 * 417 * A browse DNS response can include SRV, TXT, and AAAA records for the service instances that are enumerated. This is 418 * a SHOULD and not a MUST requirement, and servers/resolvers are not required to provide this. This function attempts 419 * to retrieve this info for a given service instance when available. 420 * 421 * - If no matching SRV record is found in @p aResponse, `OT_ERROR_NOT_FOUND` is returned. In this case, no additional 422 * records (no TXT and/or AAAA) are read. 423 * - If a matching SRV record is found in @p aResponse, @p aServiceInfo is updated and `OT_ERROR_NONE` is returned. 424 * - If no matching TXT record is found in @p aResponse, `mTxtDataSize` in @p aServiceInfo is set to zero. 425 * - If TXT data length is greater than `mTxtDataSize`, it is read partially and `mTxtDataTruncated` is set to true. 426 * - If no matching AAAA record is found in @p aResponse, `mHostAddress is set to all zero or unspecified address. 427 * - If there are multiple AAAA records for the host name in @p aResponse, `mHostAddress` is set to the first one. The 428 * other addresses can be retrieved using `otDnsBrowseResponseGetHostAddress()`. 429 * 430 * @param[in] aResponse A pointer to the response. 431 * @param[in] aInstanceLabel The service instance label (MUST NOT be NULL). 432 * @param[out] aServiceInfo A `ServiceInfo` to output the service instance information (MUST NOT be NULL). 433 * 434 * @retval OT_ERROR_NONE The service instance info was read. @p aServiceInfo is updated. 435 * @retval OT_ERROR_NOT_FOUND Could not find a matching SRV record for @p aInstanceLabel. 436 * @retval OT_ERROR_NO_BUFS The host name and/or TXT data could not fit in the given buffers. 437 * @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse. 438 */ 439 otError otDnsBrowseResponseGetServiceInfo(const otDnsBrowseResponse *aResponse, 440 const char *aInstanceLabel, 441 otDnsServiceInfo *aServiceInfo); 442 443 /** 444 * Gets the host IPv6 address from a DNS browse (service instance enumeration) response. 445 * 446 * MUST only be used from `otDnsBrowseCallback`. 447 * 448 * The response can include zero or more IPv6 address records. @p aIndex can be used to iterate through the list of 449 * addresses. Index zero gets the first address and so on. When we reach end of the list, `OT_ERROR_NOT_FOUND` is 450 * returned. 451 * 452 * @param[in] aResponse A pointer to the response. 453 * @param[in] aHostName The host name to get the address (MUST NOT be NULL). 454 * @param[in] aIndex The address record index to retrieve. 455 * @param[out] aAddress A pointer to a IPv6 address to output the address (MUST NOT be NULL). 456 * @param[out] aTtl A pointer to an `uint32_t` to output TTL for the address. It can be NULL if caller does 457 * not want to get the TTL. 458 * 459 * @retval OT_ERROR_NONE The address was read successfully. 460 * @retval OT_ERROR_NOT_FOUND No address record for @p aHostname in @p aResponse at @p aIndex. 461 * @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse. 462 */ 463 otError otDnsBrowseResponseGetHostAddress(const otDnsBrowseResponse *aResponse, 464 const char *aHostName, 465 uint16_t aIndex, 466 otIp6Address *aAddress, 467 uint32_t *aTtl); 468 469 /** 470 * An opaque representation of a response to a service instance resolution DNS query. 471 * 472 * Pointers to instance of this type are provided from callback `otDnsAddressCallback`. 473 */ 474 typedef struct otDnsServiceResponse otDnsServiceResponse; 475 476 /** 477 * Pointer is called when a DNS response is received for a service instance resolution query. 478 * 479 * Within this callback the user can use `otDnsServiceResponseGet{Item}()` functions along with the @p aResponse 480 * pointer to get more info about the response. 481 * 482 * The @p aResponse pointer can only be used within this callback and after returning from this function it will not 483 * stay valid, so the user MUST NOT retain the @p aResponse pointer for later use. 484 * 485 * @param[in] aError The result of the DNS transaction. 486 * @param[in] aResponse A pointer to the response (it is always non-NULL). 487 * @param[in] aContext A pointer to application-specific context. 488 * 489 * For the full list of possible values for @p aError, please see `otDnsAddressCallback()`. 490 */ 491 typedef void (*otDnsServiceCallback)(otError aError, const otDnsServiceResponse *aResponse, void *aContext); 492 493 /** 494 * Starts a DNS service instance resolution for a given service instance. 495 * 496 * Is available when `OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE` is enabled. 497 * 498 * The @p aConfig can be NULL. In this case the default config (from `otDnsClientGetDefaultConfig()`) will be used as 499 * the config for this query. In a non-NULL @p aConfig, some of the fields can be left unspecified (value zero). The 500 * unspecified fields are then replaced by the values from the default config. 501 * 502 * The function sends queries for SRV and/or TXT records for the given service instance. The `mServiceMode` field in 503 * `otDnsQueryConfig` determines which records to query (SRV only, TXT only, or both SRV and TXT) and how to perform 504 * the query (together in the same message, separately in parallel, or in optimized mode where client will try in the 505 * same message first and then separately if it fails to get a response). 506 * 507 * The SRV record provides information about service port, priority, and weight along with the host name associated 508 * with the service instance. This function DOES NOT perform address resolution for the host name discovered from SRV 509 * record. The server/resolver may provide AAAA/A record(s) for the host name in the Additional Data section of the 510 * response to SRV/TXT query and this information can be retrieved using `otDnsServiceResponseGetServiceInfo()` in 511 * `otDnsServiceCallback`. Users of this API MUST NOT assume that host address will always be available from 512 * `otDnsServiceResponseGetServiceInfo()`. 513 * 514 * @param[in] aInstance A pointer to an OpenThread instance. 515 * @param[in] aInstanceLabel The service instance label. 516 * @param[in] aServiceName The service name (together with @p aInstanceLabel form full instance name). 517 * @param[in] aCallback A function pointer that shall be called on response reception or time-out. 518 * @param[in] aContext A pointer to arbitrary context information. 519 * @param[in] aConfig A pointer to the config to use for this query. 520 * 521 * @retval OT_ERROR_NONE Query sent successfully. @p aCallback will be invoked to report the status. 522 * @retval OT_ERROR_NO_BUFS Insufficient buffer to prepare and send query. 523 * @retval OT_ERROR_INVALID_ARGS @p aInstanceLabel is NULL. 524 */ 525 otError otDnsClientResolveService(otInstance *aInstance, 526 const char *aInstanceLabel, 527 const char *aServiceName, 528 otDnsServiceCallback aCallback, 529 void *aContext, 530 const otDnsQueryConfig *aConfig); 531 532 /** 533 * Starts a DNS service instance resolution for a given service instance, with a potential follow-up 534 * address resolution for the host name discovered for the service instance. 535 * 536 * Is available when `OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE` is enabled. 537 * 538 * The @p aConfig can be NULL. In this case the default config (from `otDnsClientGetDefaultConfig()`) will be used as 539 * the config for this query. In a non-NULL @p aConfig, some of the fields can be left unspecified (value zero). The 540 * unspecified fields are then replaced by the values from the default config. This function cannot be used with 541 * `mServiceMode` in DNS config set to `OT_DNS_SERVICE_MODE_TXT` (i.e., querying for TXT record only) and will return 542 * `OT_ERROR_INVALID_ARGS`. 543 * 544 * Behaves similarly to `otDnsClientResolveService()` sending queries for SRV and TXT records. However, 545 * if the server/resolver does not provide AAAA/A records for the host name in the response to SRV query (in the 546 * Additional Data section), it will perform host name resolution (sending an AAAA query) for the discovered host name 547 * from the SRV record. The callback @p aCallback is invoked when responses for all queries are received (i.e., both 548 * service and host address resolutions are finished). 549 * 550 * @param[in] aInstance A pointer to an OpenThread instance. 551 * @param[in] aInstanceLabel The service instance label. 552 * @param[in] aServiceName The service name (together with @p aInstanceLabel form full instance name). 553 * @param[in] aCallback A function pointer that shall be called on response reception or time-out. 554 * @param[in] aContext A pointer to arbitrary context information. 555 * @param[in] aConfig A pointer to the config to use for this query. 556 * 557 * @retval OT_ERROR_NONE Query sent successfully. @p aCallback will be invoked to report the status. 558 * @retval OT_ERROR_NO_BUFS Insufficient buffer to prepare and send query. 559 * @retval OT_ERROR_INVALID_ARGS @p aInstanceLabel is NULL, or @p aConfig is invalid. 560 */ 561 otError otDnsClientResolveServiceAndHostAddress(otInstance *aInstance, 562 const char *aInstanceLabel, 563 const char *aServiceName, 564 otDnsServiceCallback aCallback, 565 void *aContext, 566 const otDnsQueryConfig *aConfig); 567 568 /** 569 * Gets the service instance name associated with a DNS service instance resolution response. 570 * 571 * MUST only be used from `otDnsServiceCallback`. 572 * 573 * @param[in] aResponse A pointer to the response. 574 * @param[out] aLabelBuffer A buffer to char array to output the service instance label (MUST NOT be NULL). 575 * @param[in] aLabelBufferSize The size of @p aLabelBuffer. 576 * @param[out] aNameBuffer A buffer to char array to output the rest of service name (can be NULL if user is 577 * not interested in getting the name. 578 * @param[in] aNameBufferSize The size of @p aNameBuffer. 579 * 580 * @retval OT_ERROR_NONE The service name was read successfully. 581 * @retval OT_ERROR_NO_BUFS Either the label or name does not fit in the given buffers. 582 */ 583 otError otDnsServiceResponseGetServiceName(const otDnsServiceResponse *aResponse, 584 char *aLabelBuffer, 585 uint8_t aLabelBufferSize, 586 char *aNameBuffer, 587 uint16_t aNameBufferSize); 588 589 /** 590 * Gets info for a service instance from a DNS service instance resolution response. 591 * 592 * MUST only be used from a `otDnsServiceCallback` triggered from `otDnsClientResolveService()` or 593 * `otDnsClientResolveServiceAndHostAddress()`. 594 * 595 * When this is is used from a `otDnsClientResolveService()` callback, the DNS response from server/resolver may 596 * include AAAA records in its Additional Data section for the host name associated with the service instance that is 597 * resolved. This is a SHOULD and not a MUST requirement so servers/resolvers are not required to provide this. This 598 * function attempts to parse AAAA record(s) if included in the response. If it is not included `mHostAddress` is set 599 * to all zeros (unspecified address). To also resolve the host address, user can use the DNS client API function 600 * `otDnsClientResolveServiceAndHostAddress()` which will perform service resolution followed up by a host name 601 * address resolution query (when AAAA records are not provided by server/resolver in the SRV query response). 602 * 603 * - If a matching SRV record is found in @p aResponse, @p aServiceInfo is updated. 604 * - If no matching SRV record is found, `OT_ERROR_NOT_FOUND` is returned unless the query config for this query 605 * used `OT_DNS_SERVICE_MODE_TXT` for `mServiceMode` (meaning the request was only for TXT record). In this case, we 606 * still try to parse the SRV record from Additional Data Section of response (in case server provided the info). 607 * - If no matching TXT record is found in @p aResponse, `mTxtDataSize` in @p aServiceInfo is set to zero. 608 * - If TXT data length is greater than `mTxtDataSize`, it is read partially and `mTxtDataTruncated` is set to true. 609 * - If no matching AAAA record is found in @p aResponse, `mHostAddress is set to all zero or unspecified address. 610 * - If there are multiple AAAA records for the host name in @p aResponse, `mHostAddress` is set to the first one. The 611 * other addresses can be retrieved using `otDnsServiceResponseGetHostAddress()`. 612 * 613 * @param[in] aResponse A pointer to the response. 614 * @param[out] aServiceInfo A `ServiceInfo` to output the service instance information (MUST NOT be NULL). 615 * 616 * @retval OT_ERROR_NONE The service instance info was read. @p aServiceInfo is updated. 617 * @retval OT_ERROR_NOT_FOUND Could not find a required record in @p aResponse. 618 * @retval OT_ERROR_NO_BUFS The host name and/or TXT data could not fit in the given buffers. 619 * @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse. 620 */ 621 otError otDnsServiceResponseGetServiceInfo(const otDnsServiceResponse *aResponse, otDnsServiceInfo *aServiceInfo); 622 623 /** 624 * Gets the host IPv6 address from a DNS service instance resolution response. 625 * 626 * MUST only be used from `otDnsServiceCallback`. 627 * 628 * The response can include zero or more IPv6 address records. @p aIndex can be used to iterate through the list of 629 * addresses. Index zero gets the first address and so on. When we reach end of the list, `OT_ERROR_NOT_FOUND` is 630 * returned. 631 * 632 * @param[in] aResponse A pointer to the response. 633 * @param[in] aHostName The host name to get the address (MUST NOT be NULL). 634 * @param[in] aIndex The address record index to retrieve. 635 * @param[out] aAddress A pointer to a IPv6 address to output the address (MUST NOT be NULL). 636 * @param[out] aTtl A pointer to an `uint32_t` to output TTL for the address. It can be NULL if caller does 637 * not want to get the TTL. 638 * 639 * @retval OT_ERROR_NONE The address was read successfully. 640 * @retval OT_ERROR_NOT_FOUND No address record for @p aHostname in @p aResponse at @p aIndex. 641 * @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse. 642 */ 643 otError otDnsServiceResponseGetHostAddress(const otDnsServiceResponse *aResponse, 644 const char *aHostName, 645 uint16_t aIndex, 646 otIp6Address *aAddress, 647 uint32_t *aTtl); 648 649 /** 650 * @} 651 */ 652 653 #ifdef __cplusplus 654 } // extern "C" 655 #endif 656 657 #endif // OPENTHREAD_DNS_CLIENT_H_ 658