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