1 /*
2  *  Copyright (c) 2017, 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_H_
36 #define OPENTHREAD_DNS_H_
37 
38 #include <stdint.h>
39 
40 #include <openthread/error.h>
41 #include <openthread/instance.h>
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 /**
48  * @addtogroup api-dns
49  *
50  * @brief
51  *   This module includes functions that control DNS communication.
52  *
53  * @{
54  *
55  */
56 
57 #define OT_DNS_MAX_NAME_SIZE 255 ///< Maximum name string size (includes null char at the end of string).
58 
59 #define OT_DNS_MAX_LABEL_SIZE 64 ///< Maximum label string size (include null char at the end of string).
60 
61 #define OT_DNS_TXT_KEY_MIN_LENGTH 1 ///< Minimum length of TXT record key string (RFC 6763 - section 6.4).
62 
63 #define OT_DNS_TXT_KEY_MAX_LENGTH 9 ///< Recommended maximum length of TXT record key string (RFC 6763 - section 6.4).
64 
65 #define OT_DNS_TXT_KEY_ITER_MAX_LENGTH 64 ///< Maximum length of TXT key string supported by `otDnsTxtEntryIterator`.
66 
67 /**
68  * Represents a TXT record entry representing a key/value pair (RFC 6763 - section 6.3).
69  *
70  * The string buffers pointed to by `mKey` and `mValue` MUST persist and remain unchanged after an instance of such
71  * structure is passed to OpenThread (as part of `otSrpClientService` instance).
72  *
73  * An array of `otDnsTxtEntry` entries are used in `otSrpClientService` to specify the full TXT record (a list of
74  * entries).
75  *
76  */
77 typedef struct otDnsTxtEntry
78 {
79     /**
80      * The TXT record key string.
81      *
82      * If `mKey` is not NULL, then it MUST be a null-terminated C string. The entry is treated as key/value pair with
83      * `mValue` buffer providing the value.
84      *   - The entry is encoded as follows:
85      *        - A single string length byte followed by "key=value" format (without the quotation marks).
86               - In this case, the overall encoded length must be 255 bytes or less.
87      *   - If `mValue` is NULL, then key is treated as a boolean attribute and encoded as "key" (with no `=`).
88      *   - If `mValue` is not NULL but `mValueLength` is zero, then it is treated as empty value and encoded as "key=".
89      *
90      * If `mKey` is NULL, then `mValue` buffer is treated as an already encoded TXT-DATA and is appended as is in the
91      * DNS message.
92      *
93      */
94     const char    *mKey;
95     const uint8_t *mValue;       ///< The TXT record value or already encoded TXT-DATA (depending on `mKey`).
96     uint16_t       mValueLength; ///< Number of bytes in `mValue` buffer.
97 } otDnsTxtEntry;
98 
99 /**
100  * Represents an iterator for TXT record entries (key/value pairs).
101  *
102  * The data fields in this structure are intended for use by OpenThread core and caller should not read or change them.
103  *
104  */
105 typedef struct otDnsTxtEntryIterator
106 {
107     const void *mPtr;
108     uint16_t    mData[2];
109     char        mChar[OT_DNS_TXT_KEY_ITER_MAX_LENGTH + 1];
110 } otDnsTxtEntryIterator;
111 
112 /**
113  * Initializes a TXT record iterator.
114  *
115  * The buffer pointer @p aTxtData and its content MUST persist and remain unchanged while @p aIterator object
116  * is being used.
117  *
118  * @param[in] aIterator       A pointer to the iterator to initialize (MUST NOT be NULL).
119  * @param[in] aTxtData        A pointer to buffer containing the encoded TXT data.
120  * @param[in] aTxtDataLength  The length (number of bytes) of @p aTxtData.
121  *
122  */
123 void otDnsInitTxtEntryIterator(otDnsTxtEntryIterator *aIterator, const uint8_t *aTxtData, uint16_t aTxtDataLength);
124 
125 /**
126  * Parses the TXT data from an iterator and gets the next TXT record entry (key/value pair).
127  *
128  * The @p aIterator MUST be initialized using `otDnsInitTxtEntryIterator()` before calling this function and the TXT
129  * data buffer used to initialize the iterator MUST persist and remain unchanged. Otherwise the behavior of this
130  * function is undefined.
131  *
132  * If the parsed key string length is smaller than or equal to `OT_DNS_TXT_KEY_ITER_MAX_LENGTH` the key string is
133  * returned in `mKey` in @p aEntry. But if the key is longer, then `mKey` is set to NULL and the entire encoded TXT
134  * entry string is returned in `mValue` and `mValueLength`.
135  *
136  * @param[in]  aIterator   A pointer to the iterator (MUST NOT be NULL).
137  * @param[out] aEntry      A pointer to a `otDnsTxtEntry` structure to output the parsed/read entry (MUST NOT be NULL).
138  *
139  * @retval OT_ERROR_NONE       The next entry was parsed successfully. @p aEntry is updated.
140  * @retval OT_ERROR_NOT_FOUND  No more entries in the TXT data.
141  * @retval OT_ERROR_PARSE      The TXT data from @p aIterator is not well-formed.
142  *
143  */
144 otError otDnsGetNextTxtEntry(otDnsTxtEntryIterator *aIterator, otDnsTxtEntry *aEntry);
145 
146 /**
147  * Encodes a given list of TXT record entries (key/value pairs) into TXT data (following format specified by RFC 6763).
148  *
149  * @param[in]      aTxtEntries      Pointer to an array of `otDnsTxtEntry`.
150  * @param[in]      aNumTxtEntries   Number of entries in @p aTxtEntries array.
151  * @param[out]     aTxtData         A pointer to a buffer to output the encoded TXT data.
152  * @param[in,out]  aTxtDataLength   On input, size of buffer @p aTxtData. On output, length of the encoded TXT data.
153  *
154  * @retval OT_ERROR_NONE          Encoded TXT data successfully, @p aTxtData and @p aTxtDataLength are updated.
155  * @retval OT_ERROR_INVALID_ARGS  The @p aTxtEntries is not valid.
156  * @retval OT_ERROR_NO_BUS        Could not fit the encoded data in @p aTxtData buffer with its @p aTxtDataLength.
157  *
158  */
159 otError otDnsEncodeTxtData(const otDnsTxtEntry *aTxtEntries,
160                            uint16_t             aNumTxtEntries,
161                            uint8_t             *aTxtData,
162                            uint16_t            *aTxtDataLength);
163 
164 /**
165  * Enables/disables the "DNS name compression" mode.
166  *
167  * By default DNS name compression is enabled. When disabled, DNS names are appended as full and never compressed. This
168  * is applicable to OpenThread's DNS and SRP client/server modules.
169  *
170  * This is intended for testing only and available when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` config is enabled.
171  *
172  * Note that in the case `OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE` is used, this mode applies to all OpenThread
173  * instances (i.e., calling this function enables/disables the compression mode on all OpenThread instances).
174  *
175  * @param[in] aEnabled   TRUE to enable the "DNS name compression" mode, FALSE to disable.
176  *
177  */
178 void otDnsSetNameCompressionEnabled(bool aEnabled);
179 
180 /**
181  * Indicates whether the "DNS name compression" mode is enabled or not.
182  *
183  * This is intended for testing only and available when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` config is enabled.
184  *
185  * @returns TRUE if the "DNS name compression" mode is enabled, FALSE otherwise.
186  *
187  */
188 bool otDnsIsNameCompressionEnabled(void);
189 
190 /**
191  * @}
192  *
193  */
194 
195 #ifdef __cplusplus
196 } // extern "C"
197 #endif
198 
199 #endif // OPENTHREAD_DNS_H_
200