[address-resolver] allow addr resolution using net data service (#8318)

This commit implements a new optimization in `AddressResolver`
allowing it to resolve on-mesh IPv6 addresses using info from Thread
Network Data DNS/SRP Service (Unicast Address) entries.

When determining EID-to-RLOC mapping in `Resolve()`, we first try to
match the EID against unicast addresses discovered from DNS/SRP
service entries. This is limited to entries where the address/port
info is encoded as part of server data. If a match is found the
associated RLOC16 of the BR which added the entry in Network Data
will be used (i.e., the `server16` field from Network data server
sub-TLV). This optimization is used on devices where MLE Mode
indicates they receive full Network Data and not the stable subset
(since stable subset will not provide RLOC16 info).

This commit adds a similar check in `UpdateSnoopedCacheEntry()` so
that the limited snoop cache entries are not unnecessarily used for
addresses which can be resolved using Network Data services.
This commit is contained in:
Abtin Keshavarzian
2022-10-26 01:37:40 -07:00
committed by GitHub
parent 53305d4762
commit ed31bfefb6
7 changed files with 72 additions and 10 deletions
+10
View File
@@ -106,6 +106,16 @@
#define OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY 120
#endif
/**
* @def OPENTHREAD_CONFIG_TMF_ALLOW_ADDRESS_RESOLUTION_USING_NET_DATA_SERVICES
*
* Define as 1 to allow address resolution of on-mesh addresses using Thread Network Data DNS/SRP Service entries.
*
*/
#ifndef OPENTHREAD_CONFIG_TMF_ALLOW_ADDRESS_RESOLUTION_USING_NET_DATA_SERVICES
#define OPENTHREAD_CONFIG_TMF_ALLOW_ADDRESS_RESOLUTION_USING_NET_DATA_SERVICES 1
#endif
/**
* @def OPENTHREAD_CONFIG_TMF_PENDING_DATASET_MINIMUM_DELAY
*
+43
View File
@@ -376,6 +376,10 @@ void AddressResolver::UpdateSnoopedCacheEntry(const Ip6::Address &aEid,
VerifyOrExit(Get<Mle::MleRouter>().IsFullThreadDevice());
#if OPENTHREAD_CONFIG_TMF_ALLOW_ADDRESS_RESOLUTION_USING_NET_DATA_SERVICES
VerifyOrExit(ResolveUsingNetDataServices(aEid, macAddress) != kErrorNone);
#endif
VerifyOrExit(UpdateCacheEntry(aEid, aRloc16) != kErrorNone);
// Skip if the `aRloc16` (i.e., the source of the snooped message)
@@ -470,6 +474,10 @@ Error AddressResolver::Resolve(const Ip6::Address &aEid, Mac::ShortAddress &aRlo
CacheEntry * prev = nullptr;
CacheEntryList *list;
#if OPENTHREAD_CONFIG_TMF_ALLOW_ADDRESS_RESOLUTION_USING_NET_DATA_SERVICES
VerifyOrExit(ResolveUsingNetDataServices(aEid, aRloc16) != kErrorNone);
#endif
entry = FindCacheEntry(aEid, list, prev);
if (entry == nullptr)
@@ -548,6 +556,41 @@ exit:
return error;
}
#if OPENTHREAD_CONFIG_TMF_ALLOW_ADDRESS_RESOLUTION_USING_NET_DATA_SERVICES
Error AddressResolver::ResolveUsingNetDataServices(const Ip6::Address &aEid, Mac::ShortAddress &aRloc16)
{
// Tries to resolve `aEid` Network Data DNS/SRP Unicast address
// service entries. Returns `kErrorNone` and updates `aRloc16`
// if successful, otherwise returns `kErrorNotFound`.
Error error = kErrorNotFound;
NetworkData::Service::Manager::Iterator iterator;
NetworkData::Service::DnsSrpUnicast::Info unicastInfo;
VerifyOrExit(Get<Mle::Mle>().GetDeviceMode().GetNetworkDataType() == NetworkData::kFullSet);
while (Get<NetworkData::Service::Manager>().GetNextDnsSrpUnicastInfo(iterator, unicastInfo) == kErrorNone)
{
if (unicastInfo.mOrigin != NetworkData::Service::DnsSrpUnicast::kFromServerData)
{
continue;
}
if (aEid == unicastInfo.mSockAddr.GetAddress())
{
aRloc16 = unicastInfo.mRloc16;
error = kErrorNone;
ExitNow();
}
}
exit:
return error;
}
#endif // OPENTHREAD_CONFIG_TMF_ALLOW_ADDRESS_RESOLUTION_USING_NET_DATA_SERVICES
Error AddressResolver::SendAddressQuery(const Ip6::Address &aEid)
{
Error error;
+4 -2
View File
@@ -338,8 +338,10 @@ private:
CacheEntry *NewCacheEntry(bool aSnoopedEntry);
void RemoveCacheEntry(CacheEntry &aEntry, CacheEntryList &aList, CacheEntry *aPrevEntry, Reason aReason);
Error UpdateCacheEntry(const Ip6::Address &aEid, Mac::ShortAddress aRloc16);
Error SendAddressQuery(const Ip6::Address &aEid);
Error SendAddressQuery(const Ip6::Address &aEid);
#if OPENTHREAD_CONFIG_TMF_ALLOW_ADDRESS_RESOLUTION_USING_NET_DATA_SERVICES
Error ResolveUsingNetDataServices(const Ip6::Address &aEid, Mac::ShortAddress &aRloc16);
#endif
static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
+2
View File
@@ -161,6 +161,8 @@ constexpr uint8_t kRouterSelectionJitter = 120; ///< (in sec)
constexpr uint8_t kRouterDowngradeThreshold = 23;
constexpr uint8_t kRouterUpgradeThreshold = 16;
constexpr uint16_t kInvalidRloc16 = Mac::kShortAddrInvalid; ///< Invalid RLOC16.
/**
* Threshold to accept a router upgrade request with reason `kBorderRouterRequest` (number of BRs acting as router in
* Network Data).
+3
View File
@@ -288,6 +288,7 @@ Error Manager::GetNextDnsSrpUnicastInfo(Iterator &aIterator, DnsSrpUnicast::Info
aInfo.mSockAddr.SetAddress(serverData->GetAddress());
aInfo.mSockAddr.SetPort(serverData->GetPort());
aInfo.mOrigin = DnsSrpUnicast::kFromServerData;
aInfo.mRloc16 = aIterator.mServerSubTlv->GetServer16();
ExitNow();
}
@@ -300,6 +301,7 @@ Error Manager::GetNextDnsSrpUnicastInfo(Iterator &aIterator, DnsSrpUnicast::Info
aIterator.mServerSubTlv->GetServer16());
aInfo.mSockAddr.SetPort(Encoding::BigEndian::ReadUint16(data.GetBytes()));
aInfo.mOrigin = DnsSrpUnicast::kFromServerData;
aInfo.mRloc16 = aIterator.mServerSubTlv->GetServer16();
ExitNow();
}
}
@@ -322,6 +324,7 @@ Error Manager::GetNextDnsSrpUnicastInfo(Iterator &aIterator, DnsSrpUnicast::Info
aInfo.mSockAddr.SetAddress(dnsServiceData->GetAddress());
aInfo.mSockAddr.SetPort(dnsServiceData->GetPort());
aInfo.mOrigin = DnsSrpUnicast::kFromServiceData;
aInfo.mRloc16 = Mle::kInvalidRloc16;
ExitNow();
}
+1
View File
@@ -258,6 +258,7 @@ public:
{
Ip6::SockAddr mSockAddr; ///< The socket address (IPv6 address and port) of the DNS/SRP server.
Origin mOrigin; ///< The origin of the socket address (whether from service or server data).
uint16_t mRloc16; ///< The BR RLOC16 adding the entry (only used when `mOrigin == kFromServerData`).
};
/**
+9 -8
View File
@@ -642,6 +642,7 @@ void TestNetworkDataDsnSrpServices(void)
const char * mAddress;
uint16_t mPort;
Service::DnsSrpUnicast::Origin mOrigin;
uint16_t mRloc16;
bool Matches(Service::DnsSrpUnicast::Info aInfo) const
{
@@ -650,7 +651,7 @@ void TestNetworkDataDsnSrpServices(void)
SuccessOrQuit(sockAddr.GetAddress().FromString(mAddress));
sockAddr.SetPort(mPort);
return (aInfo.mSockAddr == sockAddr) && (aInfo.mOrigin == mOrigin);
return (aInfo.mSockAddr == sockAddr) && (aInfo.mOrigin == mOrigin) && (aInfo.mRloc16 == mRloc16);
}
};
@@ -671,11 +672,11 @@ void TestNetworkDataDsnSrpServices(void)
};
const UnicastEntry kUnicastEntries[] = {
{"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, Service::DnsSrpUnicast::kFromServiceData},
{"fd00:aabb:ccdd:eeff:11:2233:4455:6677", 0xabcd, Service::DnsSrpUnicast::kFromServerData},
{"fdde:ad00:beef:0:0:ff:fe00:2800", 0x5678, Service::DnsSrpUnicast::kFromServerData},
{"fd00:1234:5678:9abc:def0:123:4567:89ab", 0x0e, Service::DnsSrpUnicast::kFromServerData},
{"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, Service::DnsSrpUnicast::kFromServerData},
{"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, Service::DnsSrpUnicast::kFromServiceData, 0xfffe},
{"fd00:aabb:ccdd:eeff:11:2233:4455:6677", 0xabcd, Service::DnsSrpUnicast::kFromServerData, 0x6c00},
{"fdde:ad00:beef:0:0:ff:fe00:2800", 0x5678, Service::DnsSrpUnicast::kFromServerData, 0x2800},
{"fd00:1234:5678:9abc:def0:123:4567:89ab", 0x0e, Service::DnsSrpUnicast::kFromServerData, 0x4c00},
{"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, Service::DnsSrpUnicast::kFromServerData, 0x6c00},
};
const uint8_t kPreferredAnycastEntryIndex = 2;
@@ -725,8 +726,8 @@ void TestNetworkDataDsnSrpServices(void)
for (const UnicastEntry &entry : kUnicastEntries)
{
SuccessOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, unicastInfo));
printf("\nunicastInfo { %s, origin:%s }", unicastInfo.mSockAddr.ToString().AsCString(),
kOriginStrings[unicastInfo.mOrigin]);
printf("\nunicastInfo { %s, origin:%s, rloc16:%04x }", unicastInfo.mSockAddr.ToString().AsCString(),
kOriginStrings[unicastInfo.mOrigin], unicastInfo.mRloc16);
VerifyOrQuit(entry.Matches(unicastInfo), "GetNextDnsSrpUnicastInfo() returned incorrect info");
}