mirror of
https://github.com/espressif/openthread.git
synced 2026-08-01 16: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:
+117
-80
@@ -290,6 +290,21 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
bool Server::Questions::IsFor(uint16_t aRrType) const
|
||||
{
|
||||
// Check if any of questions is for `aRrType`.
|
||||
|
||||
return (mFirstRrType == aRrType) || (mSecondRrType == aRrType);
|
||||
}
|
||||
|
||||
Server::Section Server::Questions::SectionFor(uint16_t aRrType) const
|
||||
{
|
||||
// Determine section to append `aRrType` record based on the
|
||||
// query questions.
|
||||
|
||||
return (IsFor(aRrType) || IsFor(kRrTypeAny)) ? kAnswerSection : kAdditionalDataSection;
|
||||
}
|
||||
|
||||
Server::ResponseCode Server::Request::ParseQuestions(uint8_t aTestMode, bool &aShouldRespond)
|
||||
{
|
||||
// Parse header and questions from a `Request` query message and
|
||||
@@ -349,7 +364,7 @@ Server::ResponseCode Server::Response::AddQuestionsFrom(const Request &aRequest)
|
||||
// service instance names with dot characters in the instance
|
||||
// label, are appended correctly.
|
||||
|
||||
SuccessOrExit(Name(*aRequest.mMessage, sizeof(Header)).AppendTo(*mMessage));
|
||||
SuccessOrExit(Name(*aRequest.mMessage, kQueryNameOffset).AppendTo(*mMessage));
|
||||
|
||||
// Check the name to include the correct domain name and determine
|
||||
// the domain name offset (for DNS name compression).
|
||||
@@ -398,26 +413,17 @@ Error Server::Response::ParseQueryName(void)
|
||||
offset = sizeof(Header);
|
||||
SuccessOrExit(error = Name::ReadName(*mMessage, offset, name));
|
||||
|
||||
if (mQuestions.IsFor(kRrTypePtr))
|
||||
{
|
||||
// `mOffsets.mServiceName` may be updated as we read labels and if we
|
||||
// determine that the query name is a sub-type service.
|
||||
mOffsets.mServiceName = sizeof(Header);
|
||||
}
|
||||
else if (mQuestions.IsFor(kRrTypeSrv) || mQuestions.IsFor(kRrTypeTxt))
|
||||
{
|
||||
mOffsets.mInstanceName = sizeof(Header);
|
||||
}
|
||||
else
|
||||
{
|
||||
mOffsets.mHostName = sizeof(Header);
|
||||
}
|
||||
// `mOffsets.mServiceName` may be updated as we read labels and if we
|
||||
// determine that the query name is a sub-type service.
|
||||
mOffsets.mServiceName = kQueryNameOffset;
|
||||
mOffsets.mInstanceName = kQueryNameOffset;
|
||||
mOffsets.mHostName = kQueryNameOffset;
|
||||
|
||||
// Read the query name labels one by one to check if the name is
|
||||
// service sub-type and also check that it is sub-domain of the
|
||||
// default domain name and determine its offset
|
||||
|
||||
offset = sizeof(Header);
|
||||
offset = kQueryNameOffset;
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -427,7 +433,8 @@ Error Server::Response::ParseQueryName(void)
|
||||
|
||||
SuccessOrExit(error = Name::ReadLabel(*mMessage, offset, label, labelLength));
|
||||
|
||||
if (mQuestions.IsFor(kRrTypePtr) && StringMatch(label, kSubLabel, kStringCaseInsensitiveMatch))
|
||||
if ((mQuestions.IsFor(kRrTypePtr) || mQuestions.IsFor(kRrTypeAny)) &&
|
||||
StringMatch(label, kSubLabel, kStringCaseInsensitiveMatch))
|
||||
{
|
||||
mOffsets.mServiceName = offset;
|
||||
}
|
||||
@@ -451,7 +458,7 @@ void Server::Response::ReadQueryName(Name::Buffer &aName) const { Server::ReadQu
|
||||
|
||||
bool Server::Response::QueryNameMatches(const char *aName) const { return Server::QueryNameMatches(*mMessage, aName); }
|
||||
|
||||
Error Server::Response::AppendQueryName(void) { return Name::AppendPointerLabel(sizeof(Header), *mMessage); }
|
||||
Error Server::Response::AppendQueryName(void) { return Name::AppendPointerLabel(kQueryNameOffset, *mMessage); }
|
||||
|
||||
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||
Error Server::Response::AppendPtrRecord(const Srp::Server::Service &aService)
|
||||
@@ -514,6 +521,7 @@ Error Server::Response::AppendSrvRecord(const char *aHostName,
|
||||
SrvRecord srvRecord;
|
||||
uint16_t recordOffset;
|
||||
Name::Buffer hostLabels;
|
||||
uint16_t nameOffset;
|
||||
|
||||
SuccessOrExit(error = Name::ExtractLabels(aHostName, kDefaultDomainName, hostLabels));
|
||||
|
||||
@@ -523,7 +531,8 @@ Error Server::Response::AppendSrvRecord(const char *aHostName,
|
||||
srvRecord.SetWeight(aWeight);
|
||||
srvRecord.SetPort(aPort);
|
||||
|
||||
SuccessOrExit(error = Name::AppendPointerLabel(mOffsets.mInstanceName, *mMessage));
|
||||
nameOffset = mQuestions.IsFor(kRrTypeAny) ? kQueryNameOffset : mOffsets.mInstanceName;
|
||||
SuccessOrExit(error = Name::AppendPointerLabel(nameOffset, *mMessage));
|
||||
|
||||
recordOffset = mMessage->GetLength();
|
||||
SuccessOrExit(error = mMessage->Append(srvRecord));
|
||||
@@ -601,6 +610,7 @@ Error Server::Response::AppendAaaaRecord(const Ip6::Address &aAddress, uint32_t
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
AaaaRecord aaaaRecord;
|
||||
uint16_t nameOffset;
|
||||
|
||||
VerifyOrExit(!aAddress.IsIp4Mapped());
|
||||
|
||||
@@ -608,7 +618,8 @@ Error Server::Response::AppendAaaaRecord(const Ip6::Address &aAddress, uint32_t
|
||||
aaaaRecord.SetTtl(aTtl);
|
||||
aaaaRecord.SetAddress(aAddress);
|
||||
|
||||
SuccessOrExit(error = Name::AppendPointerLabel(mOffsets.mHostName, *mMessage));
|
||||
nameOffset = mQuestions.IsFor(kRrTypeAny) ? kQueryNameOffset : mOffsets.mHostName;
|
||||
SuccessOrExit(error = Name::AppendPointerLabel(nameOffset, *mMessage));
|
||||
SuccessOrExit(error = mMessage->Append(aaaaRecord));
|
||||
IncResourceRecordCount();
|
||||
|
||||
@@ -621,6 +632,7 @@ Error Server::Response::AppendARecord(const Ip6::Address &aAddress, uint32_t aTt
|
||||
Error error = kErrorNone;
|
||||
ARecord aRecord;
|
||||
Ip4::Address ip4Address;
|
||||
uint16_t nameOffset;
|
||||
|
||||
SuccessOrExit(ip4Address.ExtractFromIp4MappedIp6Address(aAddress));
|
||||
|
||||
@@ -628,7 +640,8 @@ Error Server::Response::AppendARecord(const Ip6::Address &aAddress, uint32_t aTt
|
||||
aRecord.SetTtl(aTtl);
|
||||
aRecord.SetAddress(ip4Address);
|
||||
|
||||
SuccessOrExit(error = Name::AppendPointerLabel(mOffsets.mHostName, *mMessage));
|
||||
nameOffset = mQuestions.IsFor(kRrTypeAny) ? kQueryNameOffset : mOffsets.mHostName;
|
||||
SuccessOrExit(error = Name::AppendPointerLabel(nameOffset, *mMessage));
|
||||
SuccessOrExit(error = mMessage->Append(aRecord));
|
||||
IncResourceRecordCount();
|
||||
|
||||
@@ -653,6 +666,7 @@ Error Server::Response::AppendTxtRecord(const void *aTxtData, uint16_t aTxtLengt
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
TxtRecord txtRecord;
|
||||
uint16_t nameOffset;
|
||||
uint8_t emptyTxt = 0;
|
||||
|
||||
if (aTxtLength == 0)
|
||||
@@ -665,7 +679,8 @@ Error Server::Response::AppendTxtRecord(const void *aTxtData, uint16_t aTxtLengt
|
||||
txtRecord.SetTtl(aTtl);
|
||||
txtRecord.SetLength(aTxtLength);
|
||||
|
||||
SuccessOrExit(error = Name::AppendPointerLabel(mOffsets.mInstanceName, *mMessage));
|
||||
nameOffset = mQuestions.IsFor(kRrTypeAny) ? kQueryNameOffset : mOffsets.mInstanceName;
|
||||
SuccessOrExit(error = Name::AppendPointerLabel(nameOffset, *mMessage));
|
||||
SuccessOrExit(error = mMessage->Append(txtRecord));
|
||||
SuccessOrExit(error = mMessage->AppendBytes(aTxtData, aTxtLength));
|
||||
|
||||
@@ -705,7 +720,7 @@ Error Server::Response::AppendGenericRecord(uint16_t aRrType, const RecordData &
|
||||
record.Init(aRrType);
|
||||
record.SetTtl(aTtl);
|
||||
|
||||
SuccessOrExit(error = Name::AppendPointerLabel(mOffsets.mHostName, *mMessage));
|
||||
SuccessOrExit(error = Name::AppendPointerLabel(kQueryNameOffset, *mMessage));
|
||||
|
||||
recordOffset = mMessage->GetLength();
|
||||
SuccessOrExit(error = mMessage->Append(record));
|
||||
@@ -735,6 +750,7 @@ template <typename ServiceType> Error Server::Response::AppendServiceRecords(con
|
||||
|
||||
if (mSection == kAdditionalDataSection)
|
||||
{
|
||||
VerifyOrExit(!mQuestions.IsFor(kRrTypeAny));
|
||||
VerifyOrExit(!(Get<Server>().mTestMode & kTestModeEmptyAdditionalSection));
|
||||
}
|
||||
|
||||
@@ -788,7 +804,6 @@ Error Server::Response::ResolveBySrp(void)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
const Srp::Server::Service *matchedService = nullptr;
|
||||
bool found = false;
|
||||
|
||||
mSection = kAnswerSection;
|
||||
|
||||
@@ -801,18 +816,7 @@ Error Server::Response::ResolveBySrp(void)
|
||||
|
||||
if (QueryNameMatches(host.GetFullName()))
|
||||
{
|
||||
if (mQuestions.IsFor(kRrTypeAaaa) || mQuestions.IsFor(kRrTypeA))
|
||||
{
|
||||
mSection = mQuestions.SectionFor(kRrTypeAaaa);
|
||||
SuccessOrExit(error = AppendHostAddresses(host));
|
||||
}
|
||||
|
||||
if (mQuestions.IsFor(kRrTypeKey))
|
||||
{
|
||||
mSection = kAnswerSection;
|
||||
SuccessOrExit(error = AppendKeyRecord(host));
|
||||
}
|
||||
|
||||
error = ResolveUsingSrpHost(host);
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
@@ -823,52 +827,74 @@ Error Server::Response::ResolveBySrp(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mQuestions.IsFor(kRrTypePtr))
|
||||
if (QueryNameMatches(service.GetInstanceName()))
|
||||
{
|
||||
if (QueryNameMatchesService(service))
|
||||
{
|
||||
SuccessOrExit(error = AppendPtrRecord(service));
|
||||
matchedService = &service;
|
||||
}
|
||||
error = ResolveUsingSrpService(service);
|
||||
ExitNow();
|
||||
}
|
||||
else if (QueryNameMatches(service.GetInstanceName()))
|
||||
{
|
||||
matchedService = &service;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
break;
|
||||
if ((mQuestions.IsFor(kRrTypePtr) || mQuestions.IsFor(kRrTypeAny)) && QueryNameMatchesService(service))
|
||||
{
|
||||
SuccessOrExit(error = AppendPtrRecord(service));
|
||||
matchedService = &service;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrExit(matchedService != nullptr, error = kErrorNotFound);
|
||||
|
||||
if (mQuestions.IsFor(kRrTypePtr))
|
||||
{
|
||||
// Skip adding additional records, when answering a
|
||||
// PTR query with more than one answer. This is the
|
||||
// recommended behavior to keep the size of the
|
||||
// response small.
|
||||
// We append SRV/TXT/AAAA records in additional section for a PTR
|
||||
// query when there is only a single matched service. This is the
|
||||
// recommended behavior to keep the size of the response small.
|
||||
|
||||
VerifyOrExit(mHeader.GetAnswerCount() == 1);
|
||||
}
|
||||
else
|
||||
if (mQuestions.IsFor(kRrTypePtr) && (mHeader.GetAnswerCount() == 1))
|
||||
{
|
||||
if (mQuestions.IsFor(kRrTypeKey))
|
||||
{
|
||||
mSection = kAnswerSection;
|
||||
error = AppendKeyRecord(matchedService->GetHost());
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
VerifyOrExit(mQuestions.IsFor(kRrTypeSrv) || mQuestions.IsFor(kRrTypeTxt));
|
||||
error = AppendServiceRecords(*matchedService);
|
||||
}
|
||||
|
||||
error = AppendServiceRecords(*matchedService);
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error Server::Response::ResolveUsingSrpHost(const Srp::Server::Host &aHost)
|
||||
{
|
||||
// The query name is already checked to match the `aHost` name.
|
||||
|
||||
Error error = kErrorNone;
|
||||
|
||||
if (mQuestions.IsFor(kRrTypeAaaa) || mQuestions.IsFor(kRrTypeA) || mQuestions.IsFor(kRrTypeAny))
|
||||
{
|
||||
mSection = mQuestions.SectionFor(kRrTypeAaaa);
|
||||
SuccessOrExit(error = AppendHostAddresses(aHost));
|
||||
}
|
||||
|
||||
if (mQuestions.IsFor(kRrTypeKey) || mQuestions.IsFor(kRrTypeAny))
|
||||
{
|
||||
mSection = kAnswerSection;
|
||||
SuccessOrExit(error = AppendKeyRecord(aHost));
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error Server::Response::ResolveUsingSrpService(const Srp::Server::Service &aService)
|
||||
{
|
||||
// The query name is already checked to match the
|
||||
// `aService` instance name.
|
||||
|
||||
Error error = kErrorNone;
|
||||
|
||||
if (mQuestions.IsFor(kRrTypeKey) || mQuestions.IsFor(kRrTypeAny))
|
||||
{
|
||||
mSection = kAnswerSection;
|
||||
SuccessOrExit(error = AppendKeyRecord(aService.GetHost()));
|
||||
}
|
||||
|
||||
if (mQuestions.IsFor(kRrTypeSrv) || mQuestions.IsFor(kRrTypeTxt) || mQuestions.IsFor(kRrTypeAny))
|
||||
{
|
||||
SuccessOrExit(error = AppendServiceRecords(aService));
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -1573,6 +1599,7 @@ void Server::DiscoveryProxy::ReadNameFor(ProxyAction aAction,
|
||||
case kNoAction:
|
||||
break;
|
||||
case kBrowsing:
|
||||
case kQueryingRecord:
|
||||
ReadQueryName(aQuery, aName);
|
||||
break;
|
||||
case kResolvingSrv:
|
||||
@@ -1581,7 +1608,6 @@ void Server::DiscoveryProxy::ReadNameFor(ProxyAction aAction,
|
||||
break;
|
||||
case kResolvingIp6Address:
|
||||
case kResolvingIp4Address:
|
||||
case kQueryingRecord:
|
||||
ReadQueryHostName(aQuery, aInfo, aName);
|
||||
break;
|
||||
}
|
||||
@@ -1819,7 +1845,7 @@ void Server::DiscoveryProxy::StartOrStopRecordQuerier(Command aCom
|
||||
Dnssd::RecordQuerier querier;
|
||||
Name::LabelBuffer firstLabel;
|
||||
Name::Buffer nextLabels;
|
||||
uint16_t offset = aInfo.mOffsets.mHostName;
|
||||
uint16_t offset = sizeof(Header);
|
||||
uint8_t labelLength = sizeof(firstLabel);
|
||||
|
||||
IgnoreError(Dns::Name::ReadLabel(aQuery, offset, firstLabel, labelLength));
|
||||
@@ -1847,12 +1873,14 @@ bool Server::DiscoveryProxy::QueryMatches(const ProxyQuery &aQuery,
|
||||
const ProxyQueryInfo &aInfo,
|
||||
ProxyAction aAction,
|
||||
const Name::Buffer &aName,
|
||||
uint16_t aQuerierRrType) const
|
||||
uint16_t aQuerierRrType,
|
||||
RrTypeMatchMode aRrTypeMatchMode) const
|
||||
{
|
||||
// Check whether `aQuery` is performing `aAction` and
|
||||
// its name matches `aName`. The `aQuerierRrType` is only
|
||||
// used when the action is `kQueryingRecord` to indicate
|
||||
// which record is being queried.
|
||||
// its name matches `aName`. The `aQuerierRrType` and
|
||||
// `aRrTypeMatchMode` are only used when the action is
|
||||
// `kQueryingRecord` to indicate queried record type and
|
||||
// how to determine a match.
|
||||
|
||||
bool matches = false;
|
||||
|
||||
@@ -1860,12 +1888,22 @@ bool Server::DiscoveryProxy::QueryMatches(const ProxyQuery &aQuery,
|
||||
|
||||
if (aAction == kQueryingRecord)
|
||||
{
|
||||
VerifyOrExit(aInfo.mQuestions.IsFor(aQuerierRrType));
|
||||
switch (aRrTypeMatchMode)
|
||||
{
|
||||
case kRequireExactMatch:
|
||||
VerifyOrExit(aInfo.mQuestions.IsFor(aQuerierRrType));
|
||||
break;
|
||||
|
||||
case kPermitAnyOrExactMatch:
|
||||
VerifyOrExit(aInfo.mQuestions.IsFor(aQuerierRrType) || aInfo.mQuestions.IsFor(kRrTypeAny));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (aAction)
|
||||
{
|
||||
case kBrowsing:
|
||||
case kQueryingRecord:
|
||||
VerifyOrExit(QueryNameMatches(aQuery, aName));
|
||||
break;
|
||||
case kResolvingSrv:
|
||||
@@ -1874,7 +1912,6 @@ bool Server::DiscoveryProxy::QueryMatches(const ProxyQuery &aQuery,
|
||||
break;
|
||||
case kResolvingIp6Address:
|
||||
case kResolvingIp4Address:
|
||||
case kQueryingRecord:
|
||||
VerifyOrExit(QueryHostNameMatches(aQuery, aInfo, aName));
|
||||
break;
|
||||
case kNoAction:
|
||||
@@ -1902,7 +1939,7 @@ bool Server::DiscoveryProxy::HasActive(ProxyAction aAction, const Name::Buffer &
|
||||
|
||||
info.ReadFrom(query);
|
||||
|
||||
if (QueryMatches(query, info, aAction, aName, aQuerierRrType))
|
||||
if (QueryMatches(query, info, aAction, aName, aQuerierRrType, kRequireExactMatch))
|
||||
{
|
||||
has = true;
|
||||
break;
|
||||
@@ -2105,7 +2142,7 @@ void Server::DiscoveryProxy::HandleResult(ProxyAction aAction,
|
||||
|
||||
info.ReadFrom(query);
|
||||
|
||||
if (!QueryMatches(query, info, aAction, aName, querierRrType))
|
||||
if (!QueryMatches(query, info, aAction, aName, querierRrType, kPermitAnyOrExactMatch))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -319,6 +319,7 @@ private:
|
||||
static constexpr uint16_t kRrTypeKey = ResourceRecord::kTypeKey;
|
||||
static constexpr uint16_t kRrTypeAaaa = ResourceRecord::kTypeAaaa;
|
||||
static constexpr uint16_t kRrTypeSrv = ResourceRecord::kTypeSrv;
|
||||
static constexpr uint16_t kRrTypeAny = ResourceRecord::kTypeAny;
|
||||
|
||||
typedef Header::Response ResponseCode;
|
||||
|
||||
@@ -356,8 +357,8 @@ private:
|
||||
{
|
||||
Questions(void) { mFirstRrType = 0, mSecondRrType = 0; }
|
||||
|
||||
bool IsFor(uint16_t aRrType) const { return (mFirstRrType == aRrType) || (mSecondRrType == aRrType); }
|
||||
Section SectionFor(uint16_t aRrType) const { return IsFor(aRrType) ? kAnswerSection : kAdditionalDataSection; }
|
||||
bool IsFor(uint16_t aRrType) const;
|
||||
Section SectionFor(uint16_t aRrType) const;
|
||||
|
||||
uint16_t mFirstRrType;
|
||||
uint16_t mSecondRrType;
|
||||
@@ -403,6 +404,8 @@ private:
|
||||
class Response : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
public:
|
||||
static constexpr uint16_t kQueryNameOffset = sizeof(Header);
|
||||
|
||||
explicit Response(Instance &aInstance);
|
||||
ResponseCode AddQuestionsFrom(const Request &aRequest);
|
||||
|
||||
@@ -435,6 +438,8 @@ private:
|
||||
Error ExtractServiceInstanceLabel(const char *aInstanceName, Name::LabelBuffer &aLabel);
|
||||
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
|
||||
Error ResolveBySrp(void);
|
||||
Error ResolveUsingSrpHost(const Srp::Server::Host &aHost);
|
||||
Error ResolveUsingSrpService(const Srp::Server::Service &aService);
|
||||
bool QueryNameMatchesService(const Srp::Server::Service &aService) const;
|
||||
Error AppendPtrRecord(const Srp::Server::Service &aService);
|
||||
Error AppendSrvRecord(const Srp::Server::Service &aService);
|
||||
@@ -497,6 +502,12 @@ private:
|
||||
kStop,
|
||||
};
|
||||
|
||||
enum RrTypeMatchMode : uint8_t
|
||||
{
|
||||
kRequireExactMatch, // Require record type to match exactly.
|
||||
kPermitAnyOrExactMatch, // Permit ANY record type in addition to exact match.
|
||||
};
|
||||
|
||||
typedef Error (Response::*ResponseAppender)(const ProxyResult &aResult);
|
||||
|
||||
void Perform(ProxyAction aAction, ProxyQuery &aQuery, ProxyQueryInfo &aInfo);
|
||||
@@ -506,7 +517,8 @@ private:
|
||||
const ProxyQueryInfo &aInfo,
|
||||
ProxyAction aAction,
|
||||
const Name::Buffer &aName,
|
||||
uint16_t aQuerierRrType) const;
|
||||
uint16_t aQuerierRrType,
|
||||
RrTypeMatchMode aRrTypeMatchMode) const;
|
||||
void UpdateProxy(Command aCommand,
|
||||
ProxyAction aAction,
|
||||
const ProxyQuery &aQuery,
|
||||
|
||||
@@ -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()`
|
||||
|
||||
|
||||
@@ -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