mirror of
https://github.com/espressif/openthread.git
synced 2026-07-28 22:57:47 +00:00
[dns] add Name::StripName() and support in-place ExtractLabels() (#10037)
- Updates `Dns::Name::ExtractLabels()` for in-place label extraction, optimizing string operations. - Introduces `Name::StripName()` to efficiently remove a suffix name from a DNS name in place. - Updates and simplifies unit tests `test_dns` to validate new functionality.
This commit is contained in:
@@ -732,7 +732,11 @@ Error Name::ExtractLabels(const char *aName, const char *aSuffixName, char *aLab
|
||||
nameLength -= (suffixLength + 1);
|
||||
VerifyOrExit(nameLength < aLabelsSize, error = kErrorNoBufs);
|
||||
|
||||
memcpy(aLabels, aName, nameLength);
|
||||
if (aLabels != aName)
|
||||
{
|
||||
memmove(aLabels, aName, nameLength);
|
||||
}
|
||||
|
||||
aLabels[nameLength] = kNullChar;
|
||||
error = kErrorNone;
|
||||
|
||||
|
||||
@@ -1028,6 +1028,9 @@ public:
|
||||
* Both @p aName and @p aSuffixName MUST follow the same style regarding inclusion of trailing dot ('.'). Otherwise
|
||||
* `kErrorParse` is returned.
|
||||
*
|
||||
* The @p aLabels buffer may be the same as @p aName for in-place label extraction. In this case, the
|
||||
* implementation avoids unnecessary character copies.
|
||||
*
|
||||
* @param[in] aName The name to extract labels from.
|
||||
* @param[in] aSuffixName The suffix name (e.g., can be domain name).
|
||||
* @param[out] aLabels Pointer to buffer to copy the extracted labels.
|
||||
@@ -1047,6 +1050,9 @@ public:
|
||||
* Both @p aName and @p aSuffixName MUST follow the same style regarding inclusion of trailing dot ('.'). Otherwise
|
||||
* `kErrorParse` is returned.
|
||||
*
|
||||
* The @p aLabels buffer may be the same as @p aName for in-place label extraction. In this case, the
|
||||
* implementation avoids unnecessary character copies.
|
||||
*
|
||||
* @tparam kLabelsBufferSize Size of the buffer string.
|
||||
*
|
||||
* @param[in] aName The name to extract labels from.
|
||||
@@ -1064,6 +1070,28 @@ public:
|
||||
return ExtractLabels(aName, aSuffixName, aLabels, kLabelsBufferSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips a given suffix name (e.g., a domain name) from a given DNS name string, updating it in place.
|
||||
*
|
||||
* First checks that @p Name ends with the given @p aSuffixName, otherwise `kErrorParse` is returned.
|
||||
*
|
||||
* Both @p aName and @p aSuffixName MUST follow the same style regarding inclusion of trailing dot ('.'). Otherwise
|
||||
* `kErrorParse` is returned.
|
||||
*
|
||||
* @tparam kNameBufferSize The size of name buffer.
|
||||
*
|
||||
* @param[in] aName The name buffer to strip the @p aSuffixName from.
|
||||
* @param[in] aSuffixName The suffix name (e.g., can be domain name).
|
||||
*
|
||||
* @retval kErrorNone Successfully stripped the suffix name from @p aName.
|
||||
* @retval kErrorParse @p aName does not contain @p aSuffixName.
|
||||
*
|
||||
*/
|
||||
template <uint16_t kNameBufferSize> static Error StripName(char (&aName)[kNameBufferSize], const char *aSuffixName)
|
||||
{
|
||||
return ExtractLabels(aName, aSuffixName, aName, kNameBufferSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a DNS name is a sub-domain of a given domain.
|
||||
*
|
||||
|
||||
+61
-63
@@ -276,79 +276,77 @@ void TestDnsName(void)
|
||||
printf("----------------------------------------------------------------\n");
|
||||
printf("Extracting label(s) and removing domains:\n");
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa.";
|
||||
suffixName = "default.service.arpa.";
|
||||
SuccessOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name));
|
||||
VerifyOrQuit(strcmp(name, "my-service._ipps._tcp") == 0);
|
||||
{
|
||||
struct TestCase
|
||||
{
|
||||
const char *mFullName;
|
||||
const char *mSuffixName;
|
||||
const char *mLabels;
|
||||
};
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa";
|
||||
suffixName = "default.service.arpa";
|
||||
SuccessOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name));
|
||||
VerifyOrQuit(strcmp(name, "my-service._ipps._tcp") == 0);
|
||||
static const TestCase kTestCases[] = {
|
||||
{"my-service._ipps._tcp.default.service.arpa.", "default.service.arpa.", "my-service._ipps._tcp"},
|
||||
{"my-service._ipps._tcp.default.service.arpa", "default.service.arpa", "my-service._ipps._tcp"},
|
||||
{"my.service._ipps._tcp.default.service.arpa.", "_ipps._tcp.default.service.arpa.", "my.service"},
|
||||
{"my-service._ipps._tcp.default.service.arpa.", "DeFault.SerVice.ARPA.", "my-service._ipps._tcp"},
|
||||
{"my-service._ipps._tcp.default.service.arpa", "DeFault.SerVice.ARPA", "my-service._ipps._tcp"},
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa";
|
||||
suffixName = "default.service.arpa.";
|
||||
VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name) == kErrorParse);
|
||||
{"my-service._ipps._tcp.default.service.arpa", "default.service.arpa.", nullptr},
|
||||
{"my-service._ipps._tcp.default.service.arpa.", "default.service.arpa", nullptr},
|
||||
{"my-service._ipps._tcp.default.service.arpa.", "efault.service.arpa.", nullptr},
|
||||
{"my-service._ipps._tcp.default.service.arpa", "efault.service.arpa", nullptr},
|
||||
{"my-service._ipps._tcp.default.service.arpa.", "xdefault.service.arpa.", nullptr},
|
||||
{"my-service._ipps._tcp.default.service.arpa.", ".default.service.arpa.", nullptr},
|
||||
{"my-service._ipps._tcp.default.service.arpa.", "default.service.arp.", nullptr},
|
||||
{"default.service.arpa.", "default.service.arpa.", nullptr},
|
||||
{"default.service.arpa", "default.service.arpa", nullptr},
|
||||
{"efault.service.arpa.", "default.service.arpa.", nullptr},
|
||||
};
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa.";
|
||||
suffixName = "default.service.arpa";
|
||||
VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name) == kErrorParse);
|
||||
for (const TestCase &testCase : kTestCases)
|
||||
{
|
||||
Error error;
|
||||
|
||||
fullName = "my.service._ipps._tcp.default.service.arpa.";
|
||||
suffixName = "_ipps._tcp.default.service.arpa.";
|
||||
SuccessOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name));
|
||||
VerifyOrQuit(strcmp(name, "my.service") == 0);
|
||||
printf("\n");
|
||||
printf(" FullName : %s\n", testCase.mFullName);
|
||||
printf(" SuffixName : %s\n", testCase.mSuffixName);
|
||||
printf(" Extracted labels: %s\n", (testCase.mLabels != nullptr) ? testCase.mLabels : "(parse)");
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa.";
|
||||
suffixName = "DeFault.SerVice.ARPA.";
|
||||
SuccessOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name));
|
||||
VerifyOrQuit(strcmp(name, "my-service._ipps._tcp") == 0);
|
||||
error = Dns::Name::ExtractLabels(testCase.mFullName, testCase.mSuffixName, name);
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa";
|
||||
suffixName = "DeFault.SerVice.ARPA";
|
||||
SuccessOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name));
|
||||
VerifyOrQuit(strcmp(name, "my-service._ipps._tcp") == 0);
|
||||
if (testCase.mLabels != nullptr)
|
||||
{
|
||||
SuccessOrQuit(error);
|
||||
VerifyOrQuit(strcmp(name, testCase.mLabels) == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(error == kErrorParse);
|
||||
}
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa.";
|
||||
suffixName = "efault.service.arpa.";
|
||||
VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name) == kErrorParse);
|
||||
strcpy(name, testCase.mFullName);
|
||||
error = Dns::Name::StripName(name, testCase.mSuffixName);
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa";
|
||||
suffixName = "efault.service.arpa";
|
||||
VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name) == kErrorParse);
|
||||
if (testCase.mLabels != nullptr)
|
||||
{
|
||||
SuccessOrQuit(error);
|
||||
VerifyOrQuit(strcmp(name, testCase.mLabels) == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(error == kErrorParse);
|
||||
}
|
||||
}
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa.";
|
||||
suffixName = "xdefault.service.arpa.";
|
||||
VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name) == kErrorParse);
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa.";
|
||||
suffixName = "default.service.arpa.";
|
||||
SuccessOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name, 22));
|
||||
VerifyOrQuit(strcmp(name, "my-service._ipps._tcp") == 0);
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa.";
|
||||
suffixName = ".default.service.arpa.";
|
||||
VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name) == kErrorParse);
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa.";
|
||||
suffixName = "default.service.arp.";
|
||||
VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name) == kErrorParse);
|
||||
|
||||
fullName = "default.service.arpa.";
|
||||
suffixName = "default.service.arpa.";
|
||||
VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name) == kErrorParse);
|
||||
|
||||
fullName = "default.service.arpa";
|
||||
suffixName = "default.service.arpa";
|
||||
VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name) == kErrorParse);
|
||||
|
||||
fullName = "efault.service.arpa.";
|
||||
suffixName = "default.service.arpa.";
|
||||
VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name) == kErrorParse);
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa.";
|
||||
suffixName = "default.service.arpa.";
|
||||
SuccessOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name, 22));
|
||||
VerifyOrQuit(strcmp(name, "my-service._ipps._tcp") == 0);
|
||||
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa.";
|
||||
suffixName = "default.service.arpa.";
|
||||
VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name, 21) == kErrorNoBufs);
|
||||
fullName = "my-service._ipps._tcp.default.service.arpa.";
|
||||
suffixName = "default.service.arpa.";
|
||||
VerifyOrQuit(Dns::Name::ExtractLabels(fullName, suffixName, name, 21) == kErrorNoBufs);
|
||||
}
|
||||
|
||||
printf("----------------------------------------------------------------\n");
|
||||
printf("Append names, check encoded bytes, parse name and read labels:\n");
|
||||
|
||||
Reference in New Issue
Block a user