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