[dns] support longer key length in otDnsTxtEntryIterator (#9616)

This commit introduces `OT_DNS_TXT_KEY_ITER_MAX_LENGTH` with a value
of `64` to represent the maximum TXT data key length supported by
`otDnsTxtEntryIterator`. We intentionally set this value higher than
the recommended maximum key length of `9` (as specified in RFC 6763
section 6.4) to enable the parsing of TXT data when longer keys are
employed.
This commit is contained in:
Abtin Keshavarzian
2023-11-19 18:47:21 -08:00
committed by GitHub
parent 23c0fc4d4b
commit 657b973bb2
6 changed files with 38 additions and 13 deletions
+6 -4
View File
@@ -62,6 +62,8 @@ extern "C" {
#define OT_DNS_TXT_KEY_MAX_LENGTH 9 ///< Recommended maximum length of TXT record key string (RFC 6763 - section 6.4).
#define OT_DNS_TXT_KEY_ITER_MAX_LENGTH 64 ///< Maximum length of TXT key string supported by `otDnsTxtEntryIterator`.
/**
* Represents a TXT record entry representing a key/value pair (RFC 6763 - section 6.3).
*
@@ -104,7 +106,7 @@ typedef struct otDnsTxtEntryIterator
{
const void *mPtr;
uint16_t mData[2];
char mChar[OT_DNS_TXT_KEY_MAX_LENGTH + 1];
char mChar[OT_DNS_TXT_KEY_ITER_MAX_LENGTH + 1];
} otDnsTxtEntryIterator;
/**
@@ -127,9 +129,9 @@ void otDnsInitTxtEntryIterator(otDnsTxtEntryIterator *aIterator, const uint8_t *
* data buffer used to initialize the iterator MUST persist and remain unchanged. Otherwise the behavior of this
* function is undefined.
*
* If the parsed key string length is smaller than or equal to `OT_DNS_TXT_KEY_MAX_LENGTH` (recommended max key length)
* the key string is returned in `mKey` in @p aEntry. But if the key is longer, then `mKey` is set to NULL and the
* entire encoded TXT entry string is returned in `mValue` and `mValueLength`.
* If the parsed key string length is smaller than or equal to `OT_DNS_TXT_KEY_ITER_MAX_LENGTH` the key string is
* returned in `mKey` in @p aEntry. But if the key is longer, then `mKey` is set to NULL and the entire encoded TXT
* entry string is returned in `mValue` and `mValueLength`.
*
* @param[in] aIterator A pointer to the iterator (MUST NOT be NULL).
* @param[out] aEntry A pointer to a `otDnsTxtEntry` structure to output the parsed/read entry (MUST NOT be NULL).
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (371)
#define OPENTHREAD_API_VERSION (373)
/**
* @addtogroup api-instance
+3 -3
View File
@@ -953,7 +953,7 @@ Error TxtEntry::Iterator::GetNextEntry(TxtEntry &aEntry)
const char *cur;
char *keyBuffer = GetKeyBuffer();
static_assert(sizeof(mChar) == TxtEntry::kMaxKeyLength + 1, "KeyBuffer cannot fit the max key length");
static_assert(sizeof(mChar) >= TxtEntry::kMaxKeyLength + 1, "KeyBuffer cannot fit the max key length");
VerifyOrExit(GetTxtData() != nullptr, error = kErrorParse);
@@ -985,9 +985,9 @@ Error TxtEntry::Iterator::GetNextEntry(TxtEntry &aEntry)
ExitNow();
}
if (index >= kMaxKeyLength)
if (index >= sizeof(mChar) - 1)
{
// The key is larger than recommended max key length.
// The key is larger than supported key string length.
// In this case, we return the full encoded string in
// `mValue` and `mValueLength` and set `mKey` to
// `nullptr`.
+11 -3
View File
@@ -1056,6 +1056,14 @@ public:
*/
static constexpr uint8_t kMaxKeyLength = OT_DNS_TXT_KEY_MAX_LENGTH;
/**
* Maximum length of TXT key string supported by `Iterator`.
*
* This is selected to be longer than recommended `kMaxKeyLength` to handle cases where longer keys are used.
*
*/
static constexpr uint8_t kMaxIterKeyLength = OT_DNS_TXT_KEY_ITER_MAX_LENGTH;
/**
* Represents an iterator for TXT record entries (key/value pairs).
*
@@ -1083,9 +1091,9 @@ public:
* The `Iterator` instance MUST be initialized using `Init()` before calling this method and the TXT data
* buffer used to initialize the iterator MUST persist and remain unchanged.
*
* If the parsed key string length is smaller than or equal to `kMaxKeyLength` (recommended max key length)
* the key string is returned in `mKey` in @p aEntry. But if the key is longer, then `mKey` is set to NULL and
* the entire encoded TXT entry is returned in `mValue` and `mValueLength`.
* If the parsed key string length is smaller than or equal to `kMaxIterKeyLength` the key string is returned
* in `mKey` in @p aEntry. But if the key is longer, then `mKey` is set to `nullptr` the entire encoded TXT
* entry is returned in `mValue` and `mValueLength`.
*
* @param[out] aEntry A reference to a `TxtEntry` to output the parsed/read entry.
*
+1 -1
View File
@@ -263,7 +263,7 @@ Error Interface::ParsePeerInfoTxtData(const Peer::Info &aInfo,
while ((error = iterator.GetNextEntry(entry)) == kErrorNone)
{
// If the TXT data happens to have entries with key longer
// than `kMaxKeyLength`, `mKey` would be `nullptr` and full
// than `kMaxIterKeyLength`, `mKey` would be `nullptr` and full
// entry would be placed in `mValue`. We skip over such
// entries.
if (entry.mKey == nullptr)
+16 -1
View File
@@ -1302,6 +1302,9 @@ void TestDnsTxtEntry(void)
const char kKey6[] = "boolKey"; // Should be encoded as "boolKey" (without `=`).
const char kKey7[] = "emptyKey"; // Should be encoded as "emptyKey=".
const char kKey8[] = "1234567890123456789012345678901234567890123456789012345678901234567890";
const uint8_t kValue8[] = "abcd";
// Invalid key
const char kShortKey[] = "";
@@ -1312,6 +1315,17 @@ void TestDnsTxtEntry(void)
const uint8_t kEncodedTxt5[] = {12, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '=', 'a'};
const uint8_t kEncodedTxt6[] = {7, 'b', 'o', 'o', 'l', 'K', 'e', 'y'};
const uint8_t kEncodedTxt7[] = {9, 'e', 'm', 'p', 't', 'y', 'K', 'e', 'y', '='};
const uint8_t kEncodedTxt8[] = {
75, // length
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 10
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 20
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 30
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 40
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 50
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 60
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', // 70
'=', 'a', 'b', 'c', 'd',
};
const uint8_t kInvalidEncodedTxt1[] = {4, 'a', '=', 'b'}; // Incorrect length
@@ -1327,6 +1341,7 @@ void TestDnsTxtEntry(void)
Dns::TxtEntry(kKey5, kValue5, sizeof(kValue5)),
Dns::TxtEntry(kKey6, nullptr, 0),
Dns::TxtEntry(kKey7, kValue1, 0),
Dns::TxtEntry(kKey8, kValue8, sizeof(kValue8)),
};
const EncodedTxtData kEncodedTxtData[] = {
@@ -1381,7 +1396,7 @@ void TestDnsTxtEntry(void)
SuccessOrQuit(iterator.GetNextEntry(txtEntry), "TxtEntry::GetNextEntry() failed");
printf("key:\"%s\" valueLen:%d\n", txtEntry.mKey != nullptr ? txtEntry.mKey : "(null)", txtEntry.mValueLength);
if (expectedKeyLength > Dns::TxtEntry::kMaxKeyLength)
if (expectedKeyLength > Dns::TxtEntry::kMaxIterKeyLength)
{
// When the key is longer than recommended max key length,
// the full encoded string is returned in `mValue` and