[dsnsd-server] support handling of "A record" queries (#10364)

This commit adds support for responding to "A record" queries in the
DNS-SD server and discovery proxy.

If the query matches a host registered with the SRP server, the host's
IPv6 addresses are returned in the Additional Data section of the
response. If the query is resolved by the proxy, the `otPlatDnssd`
APIs are used to start/stop IPv4 address resolvers for the hostname
on the infrastructure network.

The `test_dnssd_discovery_proxy` unit test is updated to validate the
new functionality.
This commit is contained in:
Abtin Keshavarzian
2024-08-14 12:40:48 -07:00
committed by GitHub
parent ec0b2991a8
commit 1645880b8e
5 changed files with 406 additions and 64 deletions
+177 -16
View File
@@ -335,6 +335,9 @@ Server::ResponseCode Server::Request::ParseQuestions(uint8_t aTestMode, bool &aS
case ResourceRecord::kTypeAaaa:
mType = kAaaaQuery;
break;
case ResourceRecord::kTypeA:
mType = kAQuery;
break;
default:
ExitNow(rcode = Header::kResponseNotImplemented);
}
@@ -447,6 +450,7 @@ Error Server::Response::ParseQueryName(void)
break;
case kAaaaQuery:
case kAQuery:
mOffsets.mHostName = sizeof(Header);
break;
}
@@ -579,27 +583,42 @@ Error Server::Response::AppendHostAddresses(const Srp::Server::Host &aHost)
addrs = aHost.GetAddresses(addrsLength);
ttl = TimeMilli::MsecToSec(aHost.GetExpireTime() - TimerMilli::GetNow());
return AppendHostAddresses(addrs, addrsLength, ttl);
return AppendHostAddresses(kIp6AddrType, addrs, addrsLength, ttl);
}
#endif
Error Server::Response::AppendHostAddresses(const HostInfo &aHostInfo)
Error Server::Response::AppendHostAddresses(AddrType aAddrType, const HostInfo &aHostInfo)
{
return AppendHostAddresses(AsCoreTypePtr(aHostInfo.mAddresses), aHostInfo.mAddressNum, aHostInfo.mTtl);
return AppendHostAddresses(aAddrType, AsCoreTypePtr(aHostInfo.mAddresses), aHostInfo.mAddressNum, aHostInfo.mTtl);
}
Error Server::Response::AppendHostAddresses(const ServiceInstanceInfo &aInstanceInfo)
{
return AppendHostAddresses(AsCoreTypePtr(aInstanceInfo.mAddresses), aInstanceInfo.mAddressNum, aInstanceInfo.mTtl);
return AppendHostAddresses(kIp6AddrType, AsCoreTypePtr(aInstanceInfo.mAddresses), aInstanceInfo.mAddressNum,
aInstanceInfo.mTtl);
}
Error Server::Response::AppendHostAddresses(const Ip6::Address *aAddrs, uint16_t aAddrsLength, uint32_t aTtl)
Error Server::Response::AppendHostAddresses(AddrType aAddrType,
const Ip6::Address *aAddrs,
uint16_t aAddrsLength,
uint32_t aTtl)
{
Error error = kErrorNone;
for (uint16_t index = 0; index < aAddrsLength; index++)
{
SuccessOrExit(error = AppendAaaaRecord(aAddrs[index], aTtl));
const Ip6::Address &address = aAddrs[index];
switch (aAddrType)
{
case kIp6AddrType:
SuccessOrExit(error = AppendAaaaRecord(address, aTtl));
break;
case kIp4AddrType:
SuccessOrExit(error = AppendARecord(address, aTtl));
break;
}
}
exit:
@@ -608,9 +627,11 @@ exit:
Error Server::Response::AppendAaaaRecord(const Ip6::Address &aAddress, uint32_t aTtl)
{
Error error;
Error error = kErrorNone;
AaaaRecord aaaaRecord;
VerifyOrExit(!aAddress.IsIp4Mapped());
aaaaRecord.Init();
aaaaRecord.SetTtl(aTtl);
aaaaRecord.SetAddress(aAddress);
@@ -623,6 +644,26 @@ exit:
return error;
}
Error Server::Response::AppendARecord(const Ip6::Address &aAddress, uint32_t aTtl)
{
Error error = kErrorNone;
ARecord aRecord;
Ip4::Address ip4Address;
SuccessOrExit(ip4Address.ExtractFromIp4MappedIp6Address(aAddress));
aRecord.Init();
aRecord.SetTtl(aTtl);
aRecord.SetAddress(ip4Address);
SuccessOrExit(error = Name::AppendPointerLabel(mOffsets.mHostName, *mMessage));
SuccessOrExit(error = mMessage->Append(aRecord));
IncResourceRecordCount();
exit:
return error;
}
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
Error Server::Response::AppendTxtRecord(const Srp::Server::Service &aService)
{
@@ -704,6 +745,7 @@ const char *Server::Response::QueryTypeToString(QueryType aType)
"TXT", // (2) kTxtQuery
"SRV & TXT", // (3) kSrvTxtQuery
"AAAA", // (4) kAaaaQuery
"A", // (5) kAQuery
};
static_assert(0 == kPtrQuery, "kPtrQuery value is incorrect");
@@ -711,6 +753,7 @@ const char *Server::Response::QueryTypeToString(QueryType aType)
static_assert(2 == kTxtQuery, "kTxtQuery value is incorrect");
static_assert(3 == kSrvTxtQuery, "kSrvTxtQuery value is incorrect");
static_assert(4 == kAaaaQuery, "kAaaaQuery value is incorrect");
static_assert(5 == kAQuery, "kAQuery value is incorrect");
return kTypeNames[aType];
}
@@ -737,11 +780,12 @@ Error Server::Response::ResolveBySrp(void)
continue;
}
if (mType == kAaaaQuery)
if ((mType == kAaaaQuery) || (mType == kAQuery))
{
if (QueryNameMatches(host.GetFullName()))
{
error = AppendHostAddresses(host);
mSection = (mType == kAaaaQuery) ? kAnswerSection : kAdditionalDataSection;
error = AppendHostAddresses(host);
ExitNow();
}
@@ -1191,9 +1235,14 @@ exit:
void Server::Response::Answer(const HostInfo &aHostInfo, const Ip6::MessageInfo &aMessageInfo)
{
// Caller already ensures that `mType` is either `kAaaaQuery` or
// `kAQuery`.
AddrType addrType = (mType == kAaaaQuery) ? kIp6AddrType : kIp4AddrType;
mSection = kAnswerSection;
if (AppendHostAddresses(aHostInfo) != kErrorNone)
if (AppendHostAddresses(addrType, aHostInfo) != kErrorNone)
{
SetResponseCode(Header::kResponseServerFailure);
}
@@ -1238,6 +1287,7 @@ void Server::HandleDiscoveredServiceInstance(const char *aServiceFullName, const
break;
case kAaaaQuery:
case kAQuery:
break;
}
@@ -1261,12 +1311,22 @@ void Server::HandleDiscoveredHost(const char *aHostFullName, const HostInfo &aHo
info.ReadFrom(query);
if ((info.mType == kAaaaQuery) && QueryNameMatches(query, aHostFullName))
switch (info.mType)
{
Response response(GetInstance());
case kAaaaQuery:
case kAQuery:
if (QueryNameMatches(query, aHostFullName))
{
Response response(GetInstance());
RemoveQueryAndPrepareResponse(query, info, response);
response.Answer(aHostInfo, info.mMessageInfo);
RemoveQueryAndPrepareResponse(query, info, response);
response.Answer(aHostInfo, info.mMessageInfo);
}
break;
default:
break;
}
}
}
@@ -1301,6 +1361,7 @@ Server::DnsQueryType Server::GetQueryTypeAndName(const otDnssdQuery *aQuery, Dns
break;
case kAaaaQuery:
case kAQuery:
type = kDnsQueryResolveHost;
break;
}
@@ -1483,6 +1544,9 @@ void Server::DiscoveryProxy::Resolve(ProxyQuery &aQuery, ProxyQueryInfo &aInfo)
case kAaaaQuery:
action = kResolvingIp6Address;
break;
case kAQuery:
action = kResolvingIp4Address;
break;
}
Perform(action, aQuery, aInfo);
@@ -1538,6 +1602,7 @@ void Server::DiscoveryProxy::ReadNameFor(ProxyAction aAction,
ReadQueryInstanceName(aQuery, aInfo, aName);
break;
case kResolvingIp6Address:
case kResolvingIp4Address:
ReadQueryHostName(aQuery, aInfo, aName);
break;
}
@@ -1597,6 +1662,9 @@ void Server::DiscoveryProxy::UpdateProxy(Command aCommand,
case kResolvingIp6Address:
StartOrStopIp6Resolver(aCommand, aName);
break;
case kResolvingIp4Address:
StartOrStopIp4Resolver(aCommand, aName);
break;
}
}
@@ -1734,6 +1802,30 @@ void Server::DiscoveryProxy::StartOrStopIp6Resolver(Command aCommand, Name::Buff
}
}
void Server::DiscoveryProxy::StartOrStopIp4Resolver(Command aCommand, Name::Buffer &aHostName)
{
// Start or stop an IPv4 address resolver for a given host name.
Dnssd::AddressResolver resolver;
IgnoreError(StripDomainName(aHostName));
resolver.mHostName = aHostName;
resolver.mInfraIfIndex = Get<BorderRouter::InfraIf>().GetIfIndex();
resolver.mCallback = HandleIp4AddressResult;
switch (aCommand)
{
case kStart:
Get<Dnssd>().StartIp4AddressResolver(resolver);
break;
case kStop:
Get<Dnssd>().StopIp4AddressResolver(resolver);
break;
}
}
bool Server::DiscoveryProxy::QueryMatches(const ProxyQuery &aQuery,
const ProxyQueryInfo &aInfo,
ProxyAction aAction,
@@ -1756,6 +1848,7 @@ bool Server::DiscoveryProxy::QueryMatches(const ProxyQuery &aQuery,
VerifyOrExit(QueryInstanceNameMatches(aQuery, aInfo, aName));
break;
case kResolvingIp6Address:
case kResolvingIp4Address:
VerifyOrExit(QueryHostNameMatches(aQuery, aInfo, aName));
break;
case kNoAction:
@@ -1892,7 +1985,46 @@ void Server::DiscoveryProxy::HandleIp6AddressResult(const Dnssd::AddressResult &
VerifyOrExit(hasValidAddress);
ConstructFullName(aResult.mHostName, fullHostName);
HandleResult(kResolvingIp6Address, fullHostName, &Response::AppendHostAddresses, ProxyResult(aResult));
HandleResult(kResolvingIp6Address, fullHostName, &Response::AppendHostIp6Addresses, ProxyResult(aResult));
exit:
return;
}
void Server::DiscoveryProxy::HandleIp4AddressResult(otInstance *aInstance, const otPlatDnssdAddressResult *aResult)
{
AsCoreType(aInstance).Get<Server>().mDiscoveryProxy.HandleIp4AddressResult(*aResult);
}
void Server::DiscoveryProxy::HandleIp4AddressResult(const Dnssd::AddressResult &aResult)
{
bool hasValidAddress = false;
Name::Buffer fullHostName;
VerifyOrExit(mIsRunning);
VerifyOrExit(aResult.mInfraIfIndex == Get<BorderRouter::InfraIf>().GetIfIndex());
for (uint16_t index = 0; index < aResult.mAddressesLength; index++)
{
const Dnssd::AddressAndTtl &entry = aResult.mAddresses[index];
const Ip6::Address &address = AsCoreType(&entry.mAddress);
if (entry.mTtl == 0)
{
continue;
}
if (address.IsIp4Mapped())
{
hasValidAddress = true;
break;
}
}
VerifyOrExit(hasValidAddress);
ConstructFullName(aResult.mHostName, fullHostName);
HandleResult(kResolvingIp4Address, fullHostName, &Response::AppendHostIp4Addresses, ProxyResult(aResult));
exit:
return;
@@ -1944,6 +2076,7 @@ void Server::DiscoveryProxy::HandleResult(ProxyAction aAction,
break;
case kNoAction:
case kResolvingIp6Address:
case kResolvingIp4Address:
break;
}
@@ -2038,6 +2171,10 @@ bool Server::DiscoveryProxy::IsActionForAdditionalSection(ProxyAction aAction, Q
VerifyOrExit(aQueryType == kAaaaQuery);
break;
case kResolvingIp4Address:
VerifyOrExit(aQueryType == kAQuery);
break;
case kNoAction:
case kBrowsing:
ExitNow();
@@ -2079,7 +2216,7 @@ Error Server::Response::AppendTxtRecord(const ProxyResult &aResult)
return AppendTxtRecord(txtResult->mTxtData, txtResult->mTxtDataLength, txtResult->mTtl);
}
Error Server::Response::AppendHostAddresses(const ProxyResult &aResult)
Error Server::Response::AppendHostIp6Addresses(const ProxyResult &aResult)
{
Error error = kErrorNone;
const Dnssd::AddressResult *addrResult = aResult.mAddressResult;
@@ -2108,6 +2245,30 @@ exit:
return error;
}
Error Server::Response::AppendHostIp4Addresses(const ProxyResult &aResult)
{
Error error = kErrorNone;
const Dnssd::AddressResult *addrResult = aResult.mAddressResult;
mSection = (mType == kAQuery) ? kAnswerSection : kAdditionalDataSection;
for (uint16_t index = 0; index < addrResult->mAddressesLength; index++)
{
const Dnssd::AddressAndTtl &entry = addrResult->mAddresses[index];
const Ip6::Address &address = AsCoreType(&entry.mAddress);
if (entry.mTtl == 0)
{
continue;
}
SuccessOrExit(error = AppendARecord(address, entry.mTtl));
}
exit:
return error;
}
bool Server::IsProxyAddressValid(const Ip6::Address &aAddress)
{
return !aAddress.IsLinkLocalUnicast() && !aAddress.IsMulticast() && !aAddress.IsUnspecified() &&
+41 -28
View File
@@ -326,6 +326,7 @@ private:
kTxtQuery,
kSrvTxtQuery,
kAaaaQuery,
kAQuery,
};
enum Section : uint8_t
@@ -334,6 +335,12 @@ private:
kAdditionalDataSection,
};
enum AddrType : uint8_t
{
kIp6AddrType,
kIp4AddrType,
};
#if OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE
enum ProxyAction : uint8_t
{
@@ -342,6 +349,7 @@ private:
kResolvingSrv,
kResolvingTxt,
kResolvingIp6Address,
kResolvingIp4Address
};
#endif
@@ -384,33 +392,35 @@ private:
{
public:
explicit Response(Instance &aInstance);
Error AllocateAndInitFrom(const Request &aRequest);
void InitFrom(ProxyQuery &aQuery, const ProxyQueryInfo &aInfo);
void SetResponseCode(ResponseCode aResponseCode) { mHeader.SetResponseCode(aResponseCode); }
ResponseCode AddQuestionsFrom(const Request &aRequest);
Error ParseQueryName(void);
void ReadQueryName(Name::Buffer &aName) const;
bool QueryNameMatches(const char *aName) const;
Error AppendQueryName(void);
Error AppendPtrRecord(const char *aInstanceLabel, uint32_t aTtl);
Error AppendSrvRecord(const ServiceInstanceInfo &aInstanceInfo);
Error AppendSrvRecord(const char *aHostName,
uint32_t aTtl,
uint16_t aPriority,
uint16_t aWeight,
uint16_t aPort);
Error AppendTxtRecord(const ServiceInstanceInfo &aInstanceInfo);
Error AppendTxtRecord(const void *aTxtData, uint16_t aTxtLength, uint32_t aTtl);
Error AppendHostAddresses(const HostInfo &aHostInfo);
Error AppendHostAddresses(const ServiceInstanceInfo &aInstanceInfo);
Error AppendHostAddresses(const Ip6::Address *aAddrs, uint16_t aAddrsLength, uint32_t aTtl);
Error AppendAaaaRecord(const Ip6::Address &aAddress, uint32_t aTtl);
void UpdateRecordLength(ResourceRecord &aRecord, uint16_t aOffset);
void IncResourceRecordCount(void);
void Send(const Ip6::MessageInfo &aMessageInfo);
void Answer(const HostInfo &aHostInfo, const Ip6::MessageInfo &aMessageInfo);
void Answer(const ServiceInstanceInfo &aInstanceInfo, const Ip6::MessageInfo &aMessageInfo);
Error ExtractServiceInstanceLabel(const char *aInstanceName, Name::LabelBuffer &aLabel);
Error AllocateAndInitFrom(const Request &aRequest);
void InitFrom(ProxyQuery &aQuery, const ProxyQueryInfo &aInfo);
void SetResponseCode(ResponseCode aResponseCode) { mHeader.SetResponseCode(aResponseCode); }
Error ParseQueryName(void);
void ReadQueryName(Name::Buffer &aName) const;
bool QueryNameMatches(const char *aName) const;
Error AppendQueryName(void);
Error AppendPtrRecord(const char *aInstanceLabel, uint32_t aTtl);
Error AppendSrvRecord(const ServiceInstanceInfo &aInstanceInfo);
Error AppendSrvRecord(const char *aHostName,
uint32_t aTtl,
uint16_t aPriority,
uint16_t aWeight,
uint16_t aPort);
Error AppendTxtRecord(const ServiceInstanceInfo &aInstanceInfo);
Error AppendTxtRecord(const void *aTxtData, uint16_t aTxtLength, uint32_t aTtl);
Error AppendHostAddresses(AddrType aAddrType, const HostInfo &aHostInfo);
Error AppendHostAddresses(const ServiceInstanceInfo &aInstanceInfo);
Error AppendHostAddresses(AddrType aAddrType, const Ip6::Address *aAddrs, uint16_t aAddrsLength, uint32_t aTtl);
Error AppendAaaaRecord(const Ip6::Address &aAddress, uint32_t aTtl);
Error AppendARecord(const Ip6::Address &aAddress, uint32_t aTtl);
void UpdateRecordLength(ResourceRecord &aRecord, uint16_t aOffset);
void IncResourceRecordCount(void);
void Send(const Ip6::MessageInfo &aMessageInfo);
void Answer(const HostInfo &aHostInfo, const Ip6::MessageInfo &aMessageInfo);
void Answer(const ServiceInstanceInfo &aInstanceInfo, const Ip6::MessageInfo &aMessageInfo);
Error ExtractServiceInstanceLabel(const char *aInstanceName, Name::LabelBuffer &aLabel);
#if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
Error ResolveBySrp(void);
bool QueryNameMatchesService(const Srp::Server::Service &aService) const;
@@ -422,8 +432,8 @@ private:
Error AppendPtrRecord(const ProxyResult &aResult);
Error AppendSrvRecord(const ProxyResult &aResult);
Error AppendTxtRecord(const ProxyResult &aResult);
Error AppendHostAddresses(const ProxyResult &aResult);
Error AppendHostIp6Addresses(const ProxyResult &aResult);
Error AppendHostIp4Addresses(const ProxyResult &aResult);
#endif
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
@@ -493,16 +503,19 @@ private:
void StartOrStopSrvResolver(Command aCommand, const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo);
void StartOrStopTxtResolver(Command aCommand, const ProxyQuery &aQuery, const ProxyQueryInfo &aInfo);
void StartOrStopIp6Resolver(Command aCommand, Name::Buffer &aHostName);
void StartOrStopIp4Resolver(Command aCommand, Name::Buffer &aHostName);
static void HandleBrowseResult(otInstance *aInstance, const otPlatDnssdBrowseResult *aResult);
static void HandleSrvResult(otInstance *aInstance, const otPlatDnssdSrvResult *aResult);
static void HandleTxtResult(otInstance *aInstance, const otPlatDnssdTxtResult *aResult);
static void HandleIp6AddressResult(otInstance *aInstance, const otPlatDnssdAddressResult *aResult);
static void HandleIp4AddressResult(otInstance *aInstance, const otPlatDnssdAddressResult *aResult);
void HandleBrowseResult(const Dnssd::BrowseResult &aResult);
void HandleSrvResult(const Dnssd::SrvResult &aResult);
void HandleTxtResult(const Dnssd::TxtResult &aResult);
void HandleIp6AddressResult(const Dnssd::AddressResult &aResult);
void HandleIp4AddressResult(const Dnssd::AddressResult &aResult);
void HandleResult(ProxyAction aAction,
const Name::Buffer &aName,
ResponseAppender aAppender,
@@ -196,7 +196,7 @@ class TestDnssdServerOnBr(thread_cert.TestCase):
})
# check some invalid queries
for qtype in ['A', 'CNAME']:
for qtype in ['CNAME']:
dig_result = digger.dns_dig(server_addr, host1_full_name, qtype)
self._assert_dig_result_matches(dig_result, {
'status': 'NOTIMP',
@@ -278,7 +278,7 @@ class TestDnssdServerOnMultiBr(thread_cert.TestCase):
self._verify_discovery_proxy_meshcop(br2_addr, br2.get_network_name(), host)
# 4. Check some invalid queries
for qtype in ['A', 'CNAME']:
for qtype in ['CNAME']:
dig_result = host.dns_dig(br2_addr, host1_full_name, qtype)
self._assert_dig_result_matches(dig_result, {
'status': 'NOTIMP',
+186 -18
View File
@@ -566,7 +566,7 @@ struct TxtResolverInfo : public Clearable<TxtResolverInfo>
otPlatDnssdTxtCallback mCallback;
};
struct Ip6AddrResolverInfo : public Clearable<Ip6AddrResolverInfo>
struct IpAddrResolverInfo : public Clearable<IpAddrResolverInfo>
{
bool HostNameMatches(const char *aName) const { return !strcmp(mHostName, aName); }
@@ -592,16 +592,19 @@ struct InvokeOnStart : public Clearable<InvokeOnStart>
const otPlatDnssdSrvResult *mSrvResult;
const otPlatDnssdTxtResult *mTxtResult;
const otPlatDnssdAddressResult *mIp6AddrResult;
const otPlatDnssdAddressResult *mIp4AddrResult;
};
static BrowserInfo sStartBrowserInfo;
static BrowserInfo sStopBrowserInfo;
static SrvResolverInfo sStartSrvResolverInfo;
static SrvResolverInfo sStopSrvResolverInfo;
static TxtResolverInfo sStartTxtResolverInfo;
static TxtResolverInfo sStopTxtResolverInfo;
static Ip6AddrResolverInfo sStartIp6AddrResolverInfo;
static Ip6AddrResolverInfo sStopIp6AddrResolverInfo;
static BrowserInfo sStartBrowserInfo;
static BrowserInfo sStopBrowserInfo;
static SrvResolverInfo sStartSrvResolverInfo;
static SrvResolverInfo sStopSrvResolverInfo;
static TxtResolverInfo sStartTxtResolverInfo;
static TxtResolverInfo sStopTxtResolverInfo;
static IpAddrResolverInfo sStartIp6AddrResolverInfo;
static IpAddrResolverInfo sStopIp6AddrResolverInfo;
static IpAddrResolverInfo sStartIp4AddrResolverInfo;
static IpAddrResolverInfo sStopIp4AddrResolverInfo;
static InvokeOnStart sInvokeOnStart;
@@ -615,6 +618,8 @@ void ResetPlatDnssdApiInfo(void)
sStopTxtResolverInfo.Clear();
sStartIp6AddrResolverInfo.Clear();
sStopIp6AddrResolverInfo.Clear();
sStartIp4AddrResolverInfo.Clear();
sStopIp4AddrResolverInfo.Clear();
sInvokeOnStart.Clear();
}
@@ -674,6 +679,21 @@ void InvokeIp6AddrResolverCallback(const otPlatDnssdAddressCallback aCallback, c
aCallback(sInstance, &aResult);
}
void InvokeIp4AddrResolverCallback(const otPlatDnssdAddressCallback aCallback, const otPlatDnssdAddressResult &aResult)
{
Log("Invoking Ip4 resolver callback");
Log(" hostName : %s", aResult.mHostName);
Log(" if-index : %u", aResult.mInfraIfIndex);
Log(" numAddresses : %u", aResult.mAddressesLength);
for (uint16_t index = 0; index < aResult.mAddressesLength; index++)
{
Log(" address[%u] : %s", index, AsCoreType(&aResult.mAddresses[index].mAddress).ToString().AsCString());
Log(" ttl[%u] : %u", index, aResult.mAddresses[index].mTtl);
}
aCallback(sInstance, &aResult);
}
otPlatDnssdState otPlatDnssdGetState(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
@@ -802,6 +822,40 @@ void otPlatDnssdStopIp6AddressResolver(otInstance *aInstance, const otPlatDnssdA
}
}
void otPlatDnssdStartIp4AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
{
VerifyOrQuit(aResolver != nullptr);
Log("otPlatDnssdStartIp4AddressResolver(\"%s\")", aResolver->mHostName);
VerifyOrQuit(aInstance == sInstance);
VerifyOrQuit(aResolver->mInfraIfIndex == kInfraIfIndex);
sStartIp4AddrResolverInfo.UpdateFrom(aResolver);
if (sInvokeOnStart.mIp4AddrResult != nullptr)
{
InvokeIp6AddrResolverCallback(aResolver->mCallback, *sInvokeOnStart.mIp4AddrResult);
}
}
void otPlatDnssdStopIp4AddressResolver(otInstance *aInstance, const otPlatDnssdAddressResolver *aResolver)
{
VerifyOrQuit(aResolver != nullptr);
Log("otPlatDnssdStopIp4AddressResolver(\"%s\")", aResolver->mHostName);
VerifyOrQuit(aInstance == sInstance);
VerifyOrQuit(aResolver->mInfraIfIndex == kInfraIfIndex);
sStopIp4AddrResolverInfo.UpdateFrom(aResolver);
if (sInvokeOnStart.mIp6AddrResult != nullptr)
{
InvokeIp4AddrResolverCallback(aResolver->mCallback, *sInvokeOnStart.mIp4AddrResult);
}
}
//----------------------------------------------------------------------------------------------------------------------
void TestProxyBasic(void)
@@ -810,15 +864,18 @@ void TestProxyBasic(void)
const uint8_t kTxtData[] = {3, 'A', '=', '1', 0};
Srp::Server *srpServer;
Srp::Client *srpClient;
Dns::Client *dnsClient;
Dns::ServiceDiscovery::Server *dnsServer;
Dnssd::BrowseResult browseResult;
Dnssd::SrvResult srvResult;
Dnssd::TxtResult txtResult;
Dnssd::AddressResult ip6AddrrResult;
Dnssd::AddressAndTtl addressAndTtl;
Srp::Server *srpServer;
Srp::Client *srpClient;
Dns::Client *dnsClient;
Dns::ServiceDiscovery::Server *dnsServer;
Dnssd::BrowseResult browseResult;
Dnssd::SrvResult srvResult;
Dnssd::TxtResult txtResult;
Dnssd::AddressResult ip6AddrrResult;
Dnssd::AddressResult ip4AddrrResult;
Dnssd::AddressAndTtl addressAndTtl;
NetworkData::ExternalRouteConfig routeConfig;
Ip6::Address address;
Log("--------------------------------------------------------------------------------------------");
Log("TestProxyBasic");
@@ -853,6 +910,19 @@ void TestProxyBasic(void)
AdvanceTime(2000);
VerifyOrQuit(srpClient->IsRunning());
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
Log("Add a route prefix (with NAT64 flag) to network data");
routeConfig.Clear();
SuccessOrQuit(AsCoreType(&routeConfig.mPrefix.mPrefix).FromString("64:ff9b::"));
routeConfig.mPrefix.mLength = 96;
routeConfig.mPreference = NetworkData::kRoutePreferenceMedium;
routeConfig.mNat64 = true;
routeConfig.mStable = true;
SuccessOrQuit(otBorderRouterAddRoute(sInstance, &routeConfig));
SuccessOrQuit(otBorderRouterRegister(sInstance));
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
sBrowseInfo.Reset();
@@ -870,6 +940,8 @@ void TestProxyBasic(void)
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartBrowserInfo.ServiceTypeMatches("_avenger._udp"));
@@ -896,6 +968,8 @@ void TestProxyBasic(void)
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopBrowserInfo.ServiceTypeMatches("_avenger._udp"));
VerifyOrQuit(sStopBrowserInfo.mCallback == sStartBrowserInfo.mCallback);
@@ -959,6 +1033,8 @@ void TestProxyBasic(void)
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 1);
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 1);
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopTxtResolverInfo.ServiceTypeMatches("_avenger._udp"));
VerifyOrQuit(sStopTxtResolverInfo.ServiceInstanceMatches("hulk"));
@@ -991,6 +1067,8 @@ void TestProxyBasic(void)
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 1);
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 1);
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 1);
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp6AddrResolverInfo.HostNameMatches("compound"));
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallback == sStartIp6AddrResolverInfo.mCallback);
@@ -1034,6 +1112,8 @@ void TestProxyBasic(void)
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartSrvResolverInfo.ServiceTypeMatches("_avenger._udp"));
VerifyOrQuit(sStartSrvResolverInfo.ServiceInstanceMatches("iron.man"));
@@ -1062,6 +1142,8 @@ void TestProxyBasic(void)
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sResolveServiceInfo.mCallbackCount == 0);
@@ -1120,6 +1202,8 @@ void TestProxyBasic(void)
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 1);
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 1);
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sResolveServiceInfo.mCallbackCount == 0);
@@ -1147,6 +1231,8 @@ void TestProxyBasic(void)
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 1);
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 1);
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 1);
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp6AddrResolverInfo.HostNameMatches("starktower"));
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallback == sStartIp6AddrResolverInfo.mCallback);
@@ -1185,6 +1271,8 @@ void TestProxyBasic(void)
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 1);
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp6AddrResolverInfo.HostNameMatches("earth"));
@@ -1214,6 +1302,8 @@ void TestProxyBasic(void)
VerifyOrQuit(sStopTxtResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp6AddrResolverInfo.mCallCount == 1);
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallCount == 1);
VerifyOrQuit(sStartIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStopIp6AddrResolverInfo.HostNameMatches("earth"));
VerifyOrQuit(sStopIp6AddrResolverInfo.mCallback == sStartIp6AddrResolverInfo.mCallback);
@@ -1228,6 +1318,84 @@ void TestProxyBasic(void)
VerifyOrQuit(sResolveAddressInfo.mHostAddresses[0] == AsCoreType(&addressAndTtl.mAddress));
VerifyOrQuit(sResolveAddressInfo.mTtl == kTtl);
Log("--------------------------------------------------------------------------------------------");
ResetPlatDnssdApiInfo();
sResolveAddressInfo.Reset();
Log("ResolveIp4Address()");
SuccessOrQuit(dnsClient->ResolveIp4Address("shield.default.service.arpa.", AddressCallback, sInstance));
AdvanceTime(10);
// Check that an IPv4 address resolver 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 == 1);
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 0);
VerifyOrQuit(sStartIp4AddrResolverInfo.HostNameMatches("shield"));
VerifyOrQuit(sResolveAddressInfo.mCallbackCount == 0);
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
Log("Invoke IPv4 Address Resolver callback");
SuccessOrQuit(AsCoreType(&addressAndTtl.mAddress).FromString("::ffff:1.2.3.4"));
addressAndTtl.mTtl = kTtl;
ip4AddrrResult.mHostName = "shield";
ip4AddrrResult.mInfraIfIndex = kInfraIfIndex;
ip4AddrrResult.mAddresses = &addressAndTtl;
ip4AddrrResult.mAddressesLength = 1;
InvokeIp4AddrResolverCallback(sStartIp4AddrResolverInfo.mCallback, ip4AddrrResult);
AdvanceTime(10);
// Check that the IPv4 address resolver 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 == 1);
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallCount == 1);
VerifyOrQuit(sStopIp4AddrResolverInfo.HostNameMatches("shield"));
VerifyOrQuit(sStopIp4AddrResolverInfo.mCallback == sStartIp4AddrResolverInfo.mCallback);
// Check that response is sent to client and validate it
VerifyOrQuit(sResolveAddressInfo.mCallbackCount == 1);
SuccessOrQuit(sResolveAddressInfo.mError);
VerifyOrQuit(!strcmp(sResolveAddressInfo.mHostName, "shield.default.service.arpa."));
VerifyOrQuit(sResolveAddressInfo.mNumHostAddresses == 1);
// The 1.2.3.4 address with the NAT64 prefix
SuccessOrQuit(address.FromString("64:ff9b:0:0:0:0:102:304"));
VerifyOrQuit(sResolveAddressInfo.mHostAddresses[0] == address);
VerifyOrQuit(sResolveAddressInfo.mTtl == kTtl);
VerifyOrQuit(sResolveAddressInfo.mCallbackCount == 1);
SuccessOrQuit(sResolveAddressInfo.mError);
VerifyOrQuit(!strcmp(sResolveAddressInfo.mHostName, "shield.default.service.arpa."));
VerifyOrQuit(sResolveAddressInfo.mNumHostAddresses == 1);
VerifyOrQuit(sResolveAddressInfo.mTtl == kTtl);
VerifyOrQuit(sResolveAddressInfo.mHostAddresses[0] == address);
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
Log("Stop DNS-SD server");