mirror of
https://github.com/espressif/openthread.git
synced 2026-08-07 11:17:46 +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:
@@ -687,7 +687,8 @@ struct RecordQuerierInfo : public Clearable<RecordQuerierInfo>
|
||||
mCallCount++;
|
||||
CopyString(mFirstLabel, aQuerier->mFirstLabel);
|
||||
CopyString(mNextLabels, aQuerier->mNextLabels);
|
||||
mCallback = aQuerier->mCallback;
|
||||
mRecordType = aQuerier->mRecordType;
|
||||
mCallback = aQuerier->mCallback;
|
||||
}
|
||||
|
||||
uint16_t mCallCount;
|
||||
@@ -1621,7 +1622,7 @@ void TestProxyBasic(void)
|
||||
ResetPlatDnssdApiInfo();
|
||||
sQueryRecordInfo.Reset();
|
||||
|
||||
Log("QueryRecord()");
|
||||
Log("QueryRecord() for KEY and hostname");
|
||||
SuccessOrQuit(dnsClient->QueryRecord(Dns::ResourceRecord::kTypeKey, "shield", "default.service.arpa.",
|
||||
RecordCallback, sInstance));
|
||||
AdvanceTime(10);
|
||||
@@ -1642,6 +1643,7 @@ void TestProxyBasic(void)
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mCallCount == 0);
|
||||
|
||||
VerifyOrQuit(sStartRecordQuerierInfo.NameMatches("shield", nullptr));
|
||||
VerifyOrQuit(sStartRecordQuerierInfo.mRecordType == Dns::ResourceRecord::kTypeKey);
|
||||
|
||||
VerifyOrQuit(sQueryRecordInfo.mCallbackCount == 0);
|
||||
|
||||
@@ -1676,6 +1678,7 @@ void TestProxyBasic(void)
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mCallCount == 1);
|
||||
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.NameMatches("shield", nullptr));
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mRecordType == Dns::ResourceRecord::kTypeKey);
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mCallback == sStartRecordQuerierInfo.mCallback);
|
||||
|
||||
// Check that response is sent to client and validate it
|
||||
@@ -1699,7 +1702,7 @@ void TestProxyBasic(void)
|
||||
ResetPlatDnssdApiInfo();
|
||||
sQueryRecordInfo.Reset();
|
||||
|
||||
Log("QueryRecord()");
|
||||
Log("QueryRecord() for KEY and service instance name");
|
||||
SuccessOrQuit(dnsClient->QueryRecord(Dns::ResourceRecord::kTypeKey, "iron.man",
|
||||
"_avenger._udp.default.service.arpa.", RecordCallback, sInstance));
|
||||
AdvanceTime(10);
|
||||
@@ -1720,6 +1723,7 @@ void TestProxyBasic(void)
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mCallCount == 0);
|
||||
|
||||
VerifyOrQuit(sStartRecordQuerierInfo.NameMatches("iron.man", "_avenger._udp"));
|
||||
VerifyOrQuit(sStartRecordQuerierInfo.mRecordType == Dns::ResourceRecord::kTypeKey);
|
||||
|
||||
VerifyOrQuit(sQueryRecordInfo.mCallbackCount == 0);
|
||||
|
||||
@@ -1755,6 +1759,7 @@ void TestProxyBasic(void)
|
||||
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.NameMatches("iron.man", "_avenger._udp"));
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mCallback == sStartRecordQuerierInfo.mCallback);
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mRecordType == Dns::ResourceRecord::kTypeKey);
|
||||
|
||||
// Check that response is sent to client and validate it
|
||||
|
||||
@@ -1851,6 +1856,164 @@ void TestProxyBasic(void)
|
||||
VerifyOrQuit(!memcmp(sQueryRecordInfo.mRecords[0].mDataBuffer, kTranslatedCnameData, sizeof(kTranslatedCnameData)));
|
||||
VerifyOrQuit(MapEnum(sQueryRecordInfo.mRecords[0].mSection) == Dns::Client::RecordInfo::kSectionAnswer);
|
||||
|
||||
Log("--------------------------------------------------------------------------------------------");
|
||||
|
||||
ResetPlatDnssdApiInfo();
|
||||
sQueryRecordInfo.Reset();
|
||||
|
||||
Log("QueryRecord() for ANY and host name");
|
||||
SuccessOrQuit(dnsClient->QueryRecord(Dns::ResourceRecord::kTypeAny, "shield", "default.service.arpa.",
|
||||
RecordCallback, sInstance));
|
||||
AdvanceTime(10);
|
||||
|
||||
// Check that a record querier is started
|
||||
|
||||
VerifyOrQuit(sStartBrowserInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopBrowserInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartSrvResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopSrvResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartTxtResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartRecordQuerierInfo.mCallCount == 1);
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mCallCount == 0);
|
||||
|
||||
VerifyOrQuit(sStartRecordQuerierInfo.NameMatches("shield", nullptr));
|
||||
VerifyOrQuit(sStartRecordQuerierInfo.mRecordType == Dns::ResourceRecord::kTypeAny);
|
||||
|
||||
VerifyOrQuit(sQueryRecordInfo.mCallbackCount == 0);
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
|
||||
Log("Invoke Record Querier callback");
|
||||
|
||||
recordResult.mFirstLabel = "shield";
|
||||
recordResult.mNextLabels = nullptr;
|
||||
recordResult.mRecordType = Dns::ResourceRecord::kTypeKey;
|
||||
recordResult.mRecordData = kKeyData;
|
||||
recordResult.mRecordDataLength = sizeof(kKeyData);
|
||||
recordResult.mTtl = kTtl;
|
||||
recordResult.mInfraIfIndex = kInfraIfIndex;
|
||||
|
||||
InvokeRecordQuerierCallback(sStartRecordQuerierInfo.mCallback, recordResult);
|
||||
|
||||
AdvanceTime(10);
|
||||
|
||||
// Check that the record querier is stopped
|
||||
|
||||
VerifyOrQuit(sStartBrowserInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopBrowserInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartSrvResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopSrvResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartTxtResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartRecordQuerierInfo.mCallCount == 1);
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mCallCount == 1);
|
||||
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.NameMatches("shield", nullptr));
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mCallback == sStartRecordQuerierInfo.mCallback);
|
||||
|
||||
// Check that response is sent to client and validate it
|
||||
|
||||
VerifyOrQuit(sQueryRecordInfo.mCallbackCount == 1);
|
||||
SuccessOrQuit(sQueryRecordInfo.mError);
|
||||
|
||||
VerifyOrQuit(!strcmp(sQueryRecordInfo.mQueryName, "shield.default.service.arpa."));
|
||||
VerifyOrQuit(sQueryRecordInfo.mNumRecords == 1);
|
||||
|
||||
VerifyOrQuit(!strcmp(sQueryRecordInfo.mRecords[0].mNameBuffer, "shield.default.service.arpa."));
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mRecordType == Dns::ResourceRecord::kTypeKey);
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mRecordLength == sizeof(kKeyData));
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mTtl == kTtl);
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mDataBufferSize == sizeof(kKeyData));
|
||||
VerifyOrQuit(!memcmp(sQueryRecordInfo.mRecords[0].mDataBuffer, kKeyData, sizeof(kKeyData)));
|
||||
VerifyOrQuit(MapEnum(sQueryRecordInfo.mRecords[0].mSection) == Dns::Client::RecordInfo::kSectionAnswer);
|
||||
|
||||
Log("--------------------------------------------------------------------------------------------");
|
||||
|
||||
ResetPlatDnssdApiInfo();
|
||||
sQueryRecordInfo.Reset();
|
||||
|
||||
Log("QueryRecord() for ANY and service instance name");
|
||||
SuccessOrQuit(dnsClient->QueryRecord(Dns::ResourceRecord::kTypeAny, "iron.man",
|
||||
"_avenger._udp.default.service.arpa.", RecordCallback, sInstance));
|
||||
AdvanceTime(10);
|
||||
|
||||
// Check that a record querier is started
|
||||
|
||||
VerifyOrQuit(sStartBrowserInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopBrowserInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartSrvResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopSrvResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartTxtResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartRecordQuerierInfo.mCallCount == 1);
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mCallCount == 0);
|
||||
|
||||
VerifyOrQuit(sStartRecordQuerierInfo.NameMatches("iron.man", "_avenger._udp"));
|
||||
VerifyOrQuit(sStartRecordQuerierInfo.mRecordType == Dns::ResourceRecord::kTypeAny);
|
||||
|
||||
VerifyOrQuit(sQueryRecordInfo.mCallbackCount == 0);
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
|
||||
Log("Invoke Record Querier callback");
|
||||
|
||||
recordResult.mFirstLabel = "iron.man";
|
||||
recordResult.mNextLabels = "_avenger._udp";
|
||||
recordResult.mRecordType = Dns::ResourceRecord::kTypeKey;
|
||||
recordResult.mRecordData = kKeyData;
|
||||
recordResult.mRecordDataLength = sizeof(kKeyData);
|
||||
recordResult.mTtl = kTtl;
|
||||
recordResult.mInfraIfIndex = kInfraIfIndex;
|
||||
|
||||
InvokeRecordQuerierCallback(sStartRecordQuerierInfo.mCallback, recordResult);
|
||||
|
||||
AdvanceTime(10);
|
||||
|
||||
// Check that the record querier is stopped
|
||||
|
||||
VerifyOrQuit(sStartBrowserInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopBrowserInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartSrvResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopSrvResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartTxtResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
|
||||
VerifyOrQuit(sStartRecordQuerierInfo.mCallCount == 1);
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mCallCount == 1);
|
||||
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.NameMatches("iron.man", "_avenger._udp"));
|
||||
VerifyOrQuit(sStopRecordQuerierInfo.mCallback == sStartRecordQuerierInfo.mCallback);
|
||||
|
||||
// Check that response is sent to client and validate it
|
||||
|
||||
VerifyOrQuit(sQueryRecordInfo.mCallbackCount == 1);
|
||||
SuccessOrQuit(sQueryRecordInfo.mError);
|
||||
|
||||
VerifyOrQuit(!strcmp(sQueryRecordInfo.mQueryName, "iron.man._avenger._udp.default.service.arpa."));
|
||||
VerifyOrQuit(sQueryRecordInfo.mNumRecords == 1);
|
||||
|
||||
VerifyOrQuit(!strcmp(sQueryRecordInfo.mRecords[0].mNameBuffer, "iron.man._avenger._udp.default.service.arpa."));
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mRecordType == Dns::ResourceRecord::kTypeKey);
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mRecordLength == sizeof(kKeyData));
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mTtl == kTtl);
|
||||
VerifyOrQuit(sQueryRecordInfo.mRecords[0].mDataBufferSize == sizeof(kKeyData));
|
||||
VerifyOrQuit(!memcmp(sQueryRecordInfo.mRecords[0].mDataBuffer, kKeyData, sizeof(kKeyData)));
|
||||
VerifyOrQuit(MapEnum(sQueryRecordInfo.mRecords[0].mSection) == Dns::Client::RecordInfo::kSectionAnswer);
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
|
||||
Log("Stop DNS-SD server");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user