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