[dns-header] new helper method to find i-th record matching name and type (#6124)

This commit adds a new template helper method in `ResoureRecord` to
search in a given message starting from a given offset and up to a
maximum given number of records, for the i-th occurrence of a specific
record (of given type with a matching record name). If found, it reads
the record from the message into a given record object.

This commit also updates the unit test `test_dns` to cover the behavior of
newly added helper method.
This commit is contained in:
Abtin Keshavarzian
2021-02-01 22:12:05 -08:00
committed by GitHub
parent e49d20ff02
commit b5b6cf1766
3 changed files with 189 additions and 1 deletions
+76
View File
@@ -734,6 +734,7 @@ void TestHeaderAndResourceRecords(void)
uint16_t hostNameOffset;
uint16_t answerSectionOffset;
uint16_t additionalSectionOffset;
uint16_t index;
Dns::PtrRecord ptrRecord;
Dns::SrvRecord srvRecord;
Dns::TxtRecord txtRecord;
@@ -1020,6 +1021,81 @@ void TestHeaderAndResourceRecords(void)
offset += record.GetLength();
VerifyOrQuit(offset == message->GetLength(), "offset is incorrect after additional section parse");
printf("Use FindRecord() to search for specific records:\n");
printf(" Answer Section\n");
for (index = 0; index < OT_ARRAY_LENGTH(kInstanceNames); index++)
{
offset = answerSectionOffset;
SuccessOrQuit(
Dns::ResourceRecord::FindRecord(*message, offset, kAnswerCount, index, Dns::Name(kServiceName), ptrRecord),
"FindRecord() failed");
printf(" index:%d -> \"%s\" PTR %u %d\n", index, kServiceName, ptrRecord.GetTtl(), ptrRecord.GetLength());
}
// Check `FindRecord()` failure with non-matching name, record type, or bad index.
offset = answerSectionOffset;
VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAnswerCount, index, Dns::Name(kServiceName),
ptrRecord) == OT_ERROR_NOT_FOUND,
"FindRecord() did not fail with bad index");
VerifyOrQuit(offset == answerSectionOffset, "FindRecord() changed offset on failure");
offset = answerSectionOffset;
VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAnswerCount, index, Dns::Name(kInstance1Name),
ptrRecord) == OT_ERROR_NOT_FOUND,
"FindRecord() did not fail with bad index");
VerifyOrQuit(offset == answerSectionOffset, "FindRecord() changed offset on failure");
offset = answerSectionOffset;
VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAnswerCount, index, Dns::Name(kServiceName),
txtRecord) == OT_ERROR_NOT_FOUND,
"FindRecord() did not fail with bad index");
VerifyOrQuit(offset == answerSectionOffset, "FindRecord() changed offset on failure");
printf(" Additional Section\n");
for (const char *instanceName : kInstanceNames)
{
// There is a single SRV and TXT entry for each instance
offset = additionalSectionOffset;
SuccessOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAdditionalCount, /* aIndex */ 0,
Dns::Name(instanceName), srvRecord),
"FindRecord() failed");
printf(" \"%s\" SRV %u %d %d %d %d \n", instanceName, srvRecord.GetTtl(), srvRecord.GetLength(),
srvRecord.GetPort(), srvRecord.GetWeight(), srvRecord.GetPriority());
offset = additionalSectionOffset;
SuccessOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAdditionalCount, /* aIndex */ 0,
Dns::Name(instanceName), txtRecord),
"FindRecord() failed");
printf(" \"%s\" TXT %u %d\n", instanceName, txtRecord.GetTtl(), txtRecord.GetLength());
offset = additionalSectionOffset;
VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAdditionalCount, /* aIndex */ 1,
Dns::Name(instanceName), srvRecord) == OT_ERROR_NOT_FOUND,
"FindRecord() did not fail with bad index");
offset = additionalSectionOffset;
VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAdditionalCount, /* aIndex */ 1,
Dns::Name(instanceName), txtRecord) == OT_ERROR_NOT_FOUND,
"FindRecord() did not fail with bad index");
}
for (index = 0; index < kAdditionalCount; index++)
{
offset = additionalSectionOffset;
// Find record with empty name (matching any) and any type.
SuccessOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAdditionalCount, index, Dns::Name(), record),
"FindRecord() failed");
}
offset = additionalSectionOffset;
VerifyOrQuit(Dns::ResourceRecord::FindRecord(*message, offset, kAdditionalCount, index, Dns::Name(), record) ==
OT_ERROR_NOT_FOUND,
"FindRecord() did not fail with bad index");
message->Free();
testFreeInstance(instance);
}