mirror of
https://github.com/espressif/openthread.git
synced 2026-08-12 13:47:47 +00:00
[dnssd] support ANY record type queries (#11447)
This commit updates the DNS-SD `Server` implementation to support queries for the `ANY` record type. This is supported whether a query is resolved using the SRP server or the OpenThread native Discovery Proxy. When a query is resolved using the SRP server database, all known records that match the query name and type are included in the response (e.g., AAAA and KEY records for a hostname; SRV, TXT and KEY records for a service instance name; and PTR records for service type or sub-type query names). Note that unlike mDNS, where an `ANY` query is expected to elicit all known matching records, in the case of a unicast DNS query for `ANY`, the response is only required to contain at least one matching record, not necessarily all of them. This will be the behavior when the Discovery Proxy is used to resolve a unicast DNS `ANY` query (i.e., once the first answer is received from the Discovery Proxy (mDNS), a response is prepared and sent to the client). The unit tests `test_dns_client` and `test_dnssd_discovery_proxy` are updated to validate the new `ANY` query behavior.
This commit is contained in:
@@ -823,7 +823,7 @@ void TestDnsClient(void)
|
||||
VerifyOrQuit(sAddressInfo.mError != kErrorNone);
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Validate DNS Client `QueryRecord()` for host name
|
||||
// Validate DNS Client `QueryRecord()` for host name and KEY record
|
||||
|
||||
sQueryRecordInfo.Reset();
|
||||
Log("QueryRecord(%s) for KEY RR", kHostFullName);
|
||||
@@ -850,6 +850,43 @@ void TestDnsClient(void)
|
||||
SuccessOrQuit(sQueryRecordInfo.mError);
|
||||
VerifyOrQuit(sQueryRecordInfo.mNumRecords == 0);
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Validate DNS Client `QueryRecord()` for host name and ANY record
|
||||
|
||||
sQueryRecordInfo.Reset();
|
||||
Log("QueryRecord(%s) for ANY RR", kHostFullName);
|
||||
SuccessOrQuit(dnsClient->QueryRecord(Dns::ResourceRecord::kTypeAny, kHostName, "default.service.arpa.",
|
||||
RecordCallback, sInstance));
|
||||
AdvanceTime(100);
|
||||
VerifyOrQuit(sQueryRecordInfo.mCallbackCount == 1);
|
||||
SuccessOrQuit(sQueryRecordInfo.mError);
|
||||
VerifyOrQuit(sQueryRecordInfo.mNumRecords == 3);
|
||||
|
||||
for (uint8_t index = 0; index < 3; index++)
|
||||
{
|
||||
const QueryRecordInfo::Record &record = sQueryRecordInfo.mRecords[index];
|
||||
|
||||
VerifyOrQuit(StringMatch(record.mNameBuffer, kHostFullName));
|
||||
VerifyOrQuit(MapEnum(record.mSection) == Dns::Client::RecordInfo::kSectionAnswer);
|
||||
VerifyOrQuit(record.mTtl > 0);
|
||||
|
||||
if (record.mRecordType == Dns::ResourceRecord::kTypeKey)
|
||||
{
|
||||
VerifyOrQuit(record.mRecordLength == sizeof(Dns::Ecdsa256KeyRecord));
|
||||
VerifyOrQuit(record.mDataBufferSize == sizeof(Dns::Ecdsa256KeyRecord));
|
||||
}
|
||||
else if (record.mRecordType == Dns::ResourceRecord::kTypeAaaa)
|
||||
{
|
||||
VerifyOrQuit(record.mRecordLength == sizeof(Ip6::Address));
|
||||
VerifyOrQuit(addresses.Contains(*reinterpret_cast<const Ip6::Address *>(record.mDataBuffer)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unexpected record type.
|
||||
VerifyOrQuit(false);
|
||||
}
|
||||
}
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Validate DNS Client `QueryRecord()` for service instance name and KEY record
|
||||
|
||||
@@ -925,6 +962,41 @@ void TestDnsClient(void)
|
||||
}
|
||||
}
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Validate DNS Client `QueryRecord()` for service instance name and ANY record
|
||||
|
||||
sQueryRecordInfo.Reset();
|
||||
Log("QueryRecord(%s) for ANY record", kInstance1FullName);
|
||||
SuccessOrQuit(dnsClient->QueryRecord(Dns::ResourceRecord::kTypeAny, kInstance1Label, kService1FullName,
|
||||
RecordCallback, sInstance));
|
||||
AdvanceTime(100);
|
||||
|
||||
VerifyOrQuit(sQueryRecordInfo.mCallbackCount == 1);
|
||||
SuccessOrQuit(sQueryRecordInfo.mError);
|
||||
VerifyOrQuit(sQueryRecordInfo.mNumRecords == 3);
|
||||
|
||||
for (uint8_t index = 1; index < 3; index++)
|
||||
{
|
||||
const QueryRecordInfo::Record &record = sQueryRecordInfo.mRecords[index];
|
||||
|
||||
VerifyOrQuit(StringMatch(record.mNameBuffer, kInstance1FullName));
|
||||
VerifyOrQuit(record.mRecordLength > 0);
|
||||
VerifyOrQuit(record.mTtl > 0);
|
||||
VerifyOrQuit(record.mDataBufferSize == record.mRecordLength);
|
||||
VerifyOrQuit(MapEnum(record.mSection) == Dns::Client::RecordInfo::kSectionAnswer);
|
||||
|
||||
switch (record.mRecordType)
|
||||
{
|
||||
case Dns::ResourceRecord::kTypeKey:
|
||||
case Dns::ResourceRecord::kTypeTxt:
|
||||
case Dns::ResourceRecord::kTypeSrv:
|
||||
break;
|
||||
default:
|
||||
VerifyOrQuit(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Validate DNS Client `QueryRecord()` for PTR record
|
||||
|
||||
@@ -976,6 +1048,47 @@ void TestDnsClient(void)
|
||||
}
|
||||
}
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Validate DNS Client `QueryRecord()` for service name and ANY record
|
||||
|
||||
sQueryRecordInfo.Reset();
|
||||
Log("QueryRecord(%s) for ANY record", kInstance1FullName);
|
||||
SuccessOrQuit(dnsClient->QueryRecord(Dns::ResourceRecord::kTypeAny, "_srv", "_udp.default.service.arpa.",
|
||||
RecordCallback, sInstance));
|
||||
AdvanceTime(100);
|
||||
|
||||
VerifyOrQuit(sQueryRecordInfo.mCallbackCount == 1);
|
||||
SuccessOrQuit(sQueryRecordInfo.mError);
|
||||
VerifyOrQuit(sQueryRecordInfo.mNumRecords == 1);
|
||||
|
||||
VerifyOrQuit(StringMatch(sQueryRecordInfo.mRecords[0].mNameBuffer, kService1FullName));
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mRecordType == Dns::ResourceRecord::kTypePtr);
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mRecordLength > 0);
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mTtl > 0);
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mDataBufferSize == sQueryRecordInfo.mRecords[0].mRecordLength);
|
||||
VerifyOrQuit(MapEnum(sQueryRecordInfo.mRecords[0].mSection) == Dns::Client::RecordInfo::kSectionAnswer);
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Validate DNS Client `QueryRecord()` for sub-type service name and ANY record
|
||||
|
||||
sQueryRecordInfo.Reset();
|
||||
Log("QueryRecord(%s) for ANY record", kService2SubTypeFullName);
|
||||
|
||||
SuccessOrQuit(dnsClient->QueryRecord(Dns::ResourceRecord::kTypeAny, "_best",
|
||||
"_sub._game._udp.default.service.arpa.", RecordCallback, sInstance));
|
||||
AdvanceTime(100);
|
||||
|
||||
VerifyOrQuit(sQueryRecordInfo.mCallbackCount == 1);
|
||||
SuccessOrQuit(sQueryRecordInfo.mError);
|
||||
VerifyOrQuit(sQueryRecordInfo.mNumRecords == 1);
|
||||
|
||||
VerifyOrQuit(StringMatch(sQueryRecordInfo.mRecords[0].mNameBuffer, kService2SubTypeFullName));
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mRecordType == Dns::ResourceRecord::kTypePtr);
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mRecordLength > 0);
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mTtl > 0);
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mDataBufferSize == sQueryRecordInfo.mRecords[0].mRecordLength);
|
||||
VerifyOrQuit(MapEnum(sQueryRecordInfo.mRecords[0].mSection) == Dns::Client::RecordInfo::kSectionAnswer);
|
||||
|
||||
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// Validate DNS Client `Browse()`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user