diff --git a/src/core/thread/network_data_publisher.cpp b/src/core/thread/network_data_publisher.cpp index 2a12dc42e..ef1d8a5b3 100644 --- a/src/core/thread/network_data_publisher.cpp +++ b/src/core/thread/network_data_publisher.cpp @@ -658,14 +658,10 @@ void Publisher::DnsSrpServiceEntry::Process(void) break; case kTypeUnicastMeshLocalEid: - { - Service::DnsSrpAnycast::Info anycastInfo; - CountUnicastEntries(Service::DnsSrpUnicast::kFromServerData, numEntries, numPreferredEntries); desiredNumEntries = kDesiredNumUnicast; - if (HasAnyServiceDataUnicastEntry() || - (Get().FindPreferredDnsSrpAnycastInfo(anycastInfo) == kErrorNone)) + if (HasAnyServiceDataUnicastEntry() || HasAnyAnycastEntry()) { // If there is any service data unicast entry or anycast // entry, we set the desired number of server data @@ -676,7 +672,6 @@ void Publisher::DnsSrpServiceEntry::Process(void) } break; - } case kTypeUnicast: desiredNumEntries = kDesiredNumUnicast; @@ -697,23 +692,16 @@ void Publisher::DnsSrpServiceEntry::CountAnycastEntries(uint8_t &aNumEntries, ui // "sequence number" value). We prefer the entries associated with // smaller RLCO16. - Service::DnsSrpAnycast::ServiceData serviceData(mInfo.GetSequenceNumber()); - const ServiceTlv *serviceTlv = nullptr; - ServiceData data; + Service::Manager::Iterator iterator; + Service::DnsSrpAnycast::Info anycastInfo; - data.Init(&serviceData, serviceData.GetLength()); - - while ((serviceTlv = Get().FindNextThreadService(serviceTlv, data, NetworkData::kServicePrefixMatch)) != - nullptr) + while (Get().GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNone) { - TlvIterator subTlvIterator(*serviceTlv); - const ServerTlv *serverSubTlv; - - while ((serverSubTlv = subTlvIterator.Iterate()) != nullptr) + if (anycastInfo.mSequenceNumber == mInfo.GetSequenceNumber()) { aNumEntries++; - if (IsPreferred(serverSubTlv->GetServer16())) + if (IsPreferred(anycastInfo.mRloc16)) { aNumPreferredEntries++; } @@ -721,6 +709,14 @@ void Publisher::DnsSrpServiceEntry::CountAnycastEntries(uint8_t &aNumEntries, ui } } +bool Publisher::DnsSrpServiceEntry::HasAnyAnycastEntry(void) const +{ + Service::Manager::Iterator iterator; + Service::DnsSrpAnycast::Info anycastInfo; + + return (Get().GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNone); +} + void Publisher::DnsSrpServiceEntry::CountUnicastEntries(Service::DnsSrpUnicast::Type aType, uint8_t &aNumEntries, uint8_t &aNumPreferredEntries) const diff --git a/src/core/thread/network_data_publisher.hpp b/src/core/thread/network_data_publisher.hpp index 0ef546b93..d1a3becc0 100644 --- a/src/core/thread/network_data_publisher.hpp +++ b/src/core/thread/network_data_publisher.hpp @@ -438,6 +438,7 @@ private: void Notify(Event aEvent) const; void Process(void); void CountAnycastEntries(uint8_t &aNumEntries, uint8_t &aNumPreferredEntries) const; + bool HasAnyAnycastEntry(void) const; void CountUnicastEntries(Service::DnsSrpUnicast::Type aType, uint8_t &aNumEntries, uint8_t &aNumPreferredEntries) const; diff --git a/src/core/thread/network_data_service.cpp b/src/core/thread/network_data_service.cpp index c11c03ef4..45bc7b327 100644 --- a/src/core/thread/network_data_service.cpp +++ b/src/core/thread/network_data_service.cpp @@ -168,27 +168,43 @@ exit: Error Manager::GetNextDnsSrpAnycastInfo(Iterator &aIterator, DnsSrpAnycast::Info &aInfo) const { - Error error = kErrorNone; - ServiceData serviceData; - const ServiceTlv *tlv = aIterator.mServiceTlv; - - serviceData.InitFrom(DnsSrpAnycast::kServiceData); + Error error = kErrorNone; do { - tlv = Get().FindNextThreadService(tlv, serviceData, NetworkData::kServicePrefixMatch); - VerifyOrExit(tlv != nullptr, error = kErrorNotFound); + ServiceData serviceData; - } while (tlv->GetServiceDataLength() < sizeof(DnsSrpAnycast::ServiceData)); + // Process the next Server sub-TLV in the current Service TLV. - tlv->GetServiceData(serviceData); + if (IterateToNextServer(aIterator) == kErrorNone) + { + aIterator.mServiceTlv->GetServiceData(serviceData); - Get().GetServiceAloc(tlv->GetServiceId(), aInfo.mAnycastAddress); + if (serviceData.GetLength() >= sizeof(DnsSrpAnycast::ServiceData)) + { + const DnsSrpAnycast::ServiceData *dnsServiceData = + reinterpret_cast(serviceData.GetBytes()); - aInfo.mSequenceNumber = - reinterpret_cast(serviceData.GetBytes())->GetSequenceNumber(); + Get().GetServiceAloc(aIterator.mServiceTlv->GetServiceId(), aInfo.mAnycastAddress); + aInfo.mSequenceNumber = dnsServiceData->GetSequenceNumber(); + aInfo.mRloc16 = aIterator.mServerSubTlv->GetServer16(); + ExitNow(); + } + } - aIterator.mServiceTlv = tlv; + // Find the next matching Service TLV. + + serviceData.InitFrom(DnsSrpAnycast::kServiceData); + aIterator.mServiceTlv = + Get().FindNextThreadService(aIterator.mServiceTlv, serviceData, NetworkData::kServicePrefixMatch); + aIterator.mServerSubTlv = nullptr; + + // If we have a valid Service TLV, restart the loop + // to process its Server sub-TLVs. + + } while (aIterator.mServiceTlv != nullptr); + + error = kErrorNotFound; exit: return error; diff --git a/src/core/thread/network_data_service.hpp b/src/core/thread/network_data_service.hpp index 356ad072d..612eb3885 100644 --- a/src/core/thread/network_data_service.hpp +++ b/src/core/thread/network_data_service.hpp @@ -173,6 +173,7 @@ public: { Ip6::Address mAnycastAddress; ///< The anycast address associated with the DNS/SRP servers. uint8_t mSequenceNumber; ///< Sequence number used to notify SRP client if they need to re-register. + uint16_t mRloc16; ///< The RLOC16 of the entry. }; /** diff --git a/tests/unit/test_network_data.cpp b/tests/unit/test_network_data.cpp index 8a1b4a721..ea38087de 100644 --- a/tests/unit/test_network_data.cpp +++ b/tests/unit/test_network_data.cpp @@ -635,13 +635,14 @@ void TestNetworkDataDsnSrpServices(void) { uint16_t mAloc16; uint8_t mSequenceNumber; + uint16_t mRloc16; bool Matches(Service::DnsSrpAnycast::Info aInfo) const { VerifyOrQuit(aInfo.mAnycastAddress.GetIid().IsAnycastServiceLocator()); return (aInfo.mAnycastAddress.GetIid().GetLocator() == mAloc16) && - (aInfo.mSequenceNumber == mSequenceNumber); + (aInfo.mSequenceNumber == mSequenceNumber) && (aInfo.mRloc16 == mRloc16); } }; @@ -663,19 +664,20 @@ void TestNetworkDataDsnSrpServices(void) }; const uint8_t kNetworkData[] = { - 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x28, 0x00, 0x0b, 0x08, 0x81, 0x02, 0x5c, 0xff, 0x0d, 0x02, - 0x6c, 0x00, 0x0b, 0x09, 0x82, 0x02, 0x5c, 0x03, 0x0d, 0x03, 0x4c, 0x00, 0xaa, 0x0b, 0x35, 0x83, 0x13, 0x5d, - 0xfd, 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0x00, 0x2d, 0x0e, 0xc6, 0x27, 0x55, 0x56, 0x18, 0xd9, 0x12, 0x34, - 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x6c, 0x00, 0xfd, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, - 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0xab, 0xcd, 0x0d, 0x04, 0x28, 0x00, 0x56, 0x78, 0x0b, 0x23, 0x84, 0x01, - 0x5d, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x4c, 0x00, 0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, - 0xf0, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0x00, 0x0e, 0x0d, 0x04, 0x6c, 0x00, 0xcd, 0x12, + 0x0b, 0x08, 0x80, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x28, 0x00, 0x0b, 0x08, 0x81, 0x02, 0x5c, 0xff, 0x0d, + 0x02, 0x6c, 0x00, 0x0b, 0x09, 0x82, 0x02, 0x5c, 0x03, 0x0d, 0x03, 0x4c, 0x00, 0xaa, 0x0b, 0x35, 0x83, + 0x13, 0x5d, 0xfd, 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0x00, 0x2d, 0x0e, 0xc6, 0x27, 0x55, 0x56, 0x18, + 0xd9, 0x12, 0x34, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x6c, 0x00, 0xfd, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, + 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0xab, 0xcd, 0x0d, 0x04, 0x28, 0x00, 0x56, + 0x78, 0x0b, 0x23, 0x84, 0x01, 0x5d, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x4c, 0x00, 0xfd, 0x00, 0x12, + 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0x00, 0x0e, 0x0d, 0x04, + 0x6c, 0x00, 0xcd, 0x12, 0x0b, 0x08, 0x84, 0x01, 0x5c, 0x0d, 0x02, 0x14, 0x01, 0x0d, 0x0b, 0x10, 0x83, + 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x12, 0x00, 0x0d, 0x02, 0x12, 0x01, 0x0d, 0x02, 0x16, 0x00, }; const AnycastEntry kAnycastEntries[] = { - {0xfc10, 0x02}, - {0xfc11, 0xff}, - {0xfc12, 0x03}, + {0xfc10, 0x02, 0x2800}, {0xfc11, 0xff, 0x6c00}, {0xfc12, 0x03, 0x4c00}, + {0xfc13, 0xfe, 0x1200}, {0xfc13, 0xfe, 0x1201}, {0xfc13, 0xfe, 0x1600}, }; const UnicastEntry kUnicastEntriesFromServerData[] = { @@ -691,7 +693,9 @@ void TestNetworkDataDsnSrpServices(void) {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 0x2800}, }; - const uint16_t kExpectedRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000}; + const uint16_t kExpectedRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000, 0x1200, 0x1201, 0x1600, 0x1401}; + const uint16_t kExpectedRouterRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000, 0x1200, 0x1600}; + const uint16_t kExpectedChildRlocs[] = {0x1201, 0x1401}; const uint8_t kPreferredAnycastEntryIndex = 2; @@ -712,10 +716,10 @@ void TestNetworkDataDsnSrpServices(void) VerifyRlocsArray(rlocs, kExpectedRlocs); instance->Get().FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs); - VerifyRlocsArray(rlocs, kExpectedRlocs); + VerifyRlocsArray(rlocs, kExpectedRouterRlocs); instance->Get().FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs); - VerifyOrQuit(rlocs.GetLength() == 0); + VerifyRlocsArray(rlocs, kExpectedChildRlocs); instance->Get().FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs); VerifyOrQuit(rlocs.GetLength() == 0); @@ -729,8 +733,8 @@ void TestNetworkDataDsnSrpServices(void) { SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo)); - printf("\nanycastInfo { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(), - anycastInfo.mSequenceNumber); + printf("\nanycastInfo { %s, seq:%d, rlco16:%04x }", anycastInfo.mAnycastAddress.ToString().AsCString(), + anycastInfo.mSequenceNumber, anycastInfo.mRloc16); VerifyOrQuit(entry.Matches(anycastInfo), "GetNextDnsSrpAnycastInfo() returned incorrect info"); } @@ -955,10 +959,11 @@ void TestNetworkDataDsnSrpAnycastSeqNumSelection(void) { SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo)); - printf("\n { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(), - anycastInfo.mSequenceNumber); + printf("\n { %s, seq:%d, rlco16:%04x }", anycastInfo.mAnycastAddress.ToString().AsCString(), + anycastInfo.mSequenceNumber, anycastInfo.mRloc16); VerifyOrQuit(anycastInfo.mSequenceNumber == test.mSeqNumbers[index]); + VerifyOrQuit(anycastInfo.mRloc16 == 0x5000 + index); } VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound);