diff --git a/src/core/config/tmf.h b/src/core/config/tmf.h index 5d43f73e1..0bd1f3651 100644 --- a/src/core/config/tmf.h +++ b/src/core/config/tmf.h @@ -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 * diff --git a/src/core/thread/address_resolver.cpp b/src/core/thread/address_resolver.cpp index d88f165cc..812986502 100644 --- a/src/core/thread/address_resolver.cpp +++ b/src/core/thread/address_resolver.cpp @@ -376,6 +376,10 @@ void AddressResolver::UpdateSnoopedCacheEntry(const Ip6::Address &aEid, VerifyOrExit(Get().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().GetDeviceMode().GetNetworkDataType() == NetworkData::kFullSet); + + while (Get().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; diff --git a/src/core/thread/address_resolver.hpp b/src/core/thread/address_resolver.hpp index 0b76af9be..6695fc32d 100644 --- a/src/core/thread/address_resolver.hpp +++ b/src/core/thread/address_resolver.hpp @@ -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); diff --git a/src/core/thread/mle_types.hpp b/src/core/thread/mle_types.hpp index 19f577867..44be29ea4 100644 --- a/src/core/thread/mle_types.hpp +++ b/src/core/thread/mle_types.hpp @@ -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). diff --git a/src/core/thread/network_data_service.cpp b/src/core/thread/network_data_service.cpp index 4bc60da48..7ed771452 100644 --- a/src/core/thread/network_data_service.cpp +++ b/src/core/thread/network_data_service.cpp @@ -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(); } diff --git a/src/core/thread/network_data_service.hpp b/src/core/thread/network_data_service.hpp index bd41dc775..ed8903994 100644 --- a/src/core/thread/network_data_service.hpp +++ b/src/core/thread/network_data_service.hpp @@ -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`). }; /** diff --git a/tests/unit/test_network_data.cpp b/tests/unit/test_network_data.cpp index 44df23646..9d1523b74 100644 --- a/tests/unit/test_network_data.cpp +++ b/tests/unit/test_network_data.cpp @@ -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"); }