[netdata] add version number to DNS/SRP service entries (#10752)

This commit adds a version field (`uint8_t`) to DNS/SRP Anycast and
Unicast Service entries in `NetworkData::Service::Manager`.

For Unicast entries, the version the version field is placed after
the existing fields, specifically after the IPv6 address and port number fields.
For Anycast entries it is added as the in server data as part of the
Server TLV.

When processing Network Data service entries, the version field is
optional and if absent, version number zero is assumed.

The `NetworkData::Publisher` now considers entries with the same or
higher version number when deciding whether to add or remove its own
entry, preferring those with a higher version.

In SRP client, when `AutoStart` mode is used and if there are multiple
Unicast, Service entries, the client prefers the one with larger
version number.

When selecting an anycast entry, the existing rules regarding sequence
numbers are still used. If multiple entries with the same sequence
number exist, the client will assume the minimum version number among
all such entries.

This commit also updates the `test_network_data` unit test, validating
the new format and related methods.

`test_netdata_publisher.py` is also updated to check service entries
with different version numbers.
This commit is contained in:
Abtin Keshavarzian
2024-12-23 18:59:06 -08:00
committed by GitHub
parent 588e93cd15
commit 4c378f798d
16 changed files with 611 additions and 241 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ extern "C" {
*
* @note This number versions both OpenThread platform and user APIs.
*/
#define OPENTHREAD_API_VERSION (468)
#define OPENTHREAD_API_VERSION (469)
/**
* @addtogroup api-instance
+9 -3
View File
@@ -100,8 +100,9 @@ typedef void (*otNetDataPrefixPublisherCallback)(otNetDataPublisherEvent aEvent,
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aSequenceNUmber The sequence number of DNS/SRP Anycast Service.
* @param[in] aVersion The version number to publish.
*/
void otNetDataPublishDnsSrpServiceAnycast(otInstance *aInstance, uint8_t aSequenceNUmber);
void otNetDataPublishDnsSrpServiceAnycast(otInstance *aInstance, uint8_t aSequenceNUmber, uint8_t aVersion);
/**
* Requests "DNS/SRP Service Unicast Address" to be published in the Thread Network Data.
@@ -117,8 +118,12 @@ void otNetDataPublishDnsSrpServiceAnycast(otInstance *aInstance, uint8_t aSequen
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aAddress The DNS/SRP server address to publish (MUST NOT be NULL).
* @param[in] aPort The SRP server port number to publish.
* @param[in] aVersion The version number to publish.
*/
void otNetDataPublishDnsSrpServiceUnicast(otInstance *aInstance, const otIp6Address *aAddress, uint16_t aPort);
void otNetDataPublishDnsSrpServiceUnicast(otInstance *aInstance,
const otIp6Address *aAddress,
uint16_t aPort,
uint8_t aVersion);
/**
* Requests "DNS/SRP Service Unicast Address" to be published in the Thread Network Data.
@@ -134,8 +139,9 @@ void otNetDataPublishDnsSrpServiceUnicast(otInstance *aInstance, const otIp6Addr
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aPort The SRP server port number to publish.
* @param[in] aVersion The version number to publish.
*/
void otNetDataPublishDnsSrpServiceUnicastMeshLocalEid(otInstance *aInstance, uint16_t aPort);
void otNetDataPublishDnsSrpServiceUnicastMeshLocalEid(otInstance *aInstance, uint16_t aPort, uint8_t aVersion);
/**
* Indicates whether or not currently the "DNS/SRP Service" entry is added to the Thread Network Data.
+6 -6
View File
@@ -254,20 +254,20 @@ This command requires `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE`.
The following formats are available: :
- `netdata publish dnssrp anycast <seq-num>` to publish "DNS/SRP Service Anycast Address" with a given sequence number.
- `netdata publish dnssrp unicast <address> <port>` to publish "DNS/SRP Service Unicast Address" with given address and port number info. The address/port info is included in Service TLV data.
- `netdata publish dnssrp unicast <port>` to publish "DNS/SRP Service Unicast Address" with given port number and the device's mesh-local EID for the address. The address and port info is included in Server TLV data.
- `netdata publish dnssrp anycast <seq-num> [<version>]` to publish "DNS/SRP Service Anycast Address" with a given sequence number and version.
- `netdata publish dnssrp unicast <address> <port> [<version>]` to publish "DNS/SRP Service Unicast Address" with given address, port number and version info. The address/port/version info is included in Service TLV data.
- `netdata publish dnssrp unicast <port> [<version>]` to publish "DNS/SRP Service Unicast Address" with given port number, version, and the device's mesh-local EID for the address. The address/port/version info is included in Server TLV data.
A new call to `netdata publish dnssrp [anycast|unicast] [...]` command will remove and replace any previous "DNS/SRP Service" entry that was being published (from earlier `netdata publish dnssrp [...]` commands).
```bash
> netdata publish dnssrp anycast 1
> netdata publish dnssrp anycast 1 2
Done
> netdata publish dnssrp unicast fd00::1234 51525
> netdata publish dnssrp unicast fd00::1234 51525 1
Done
> netdata publish dnssrp unicast 50152
> netdata publish dnssrp unicast 50152 2
Done
```
+51 -25
View File
@@ -244,17 +244,17 @@ template <> otError NetworkData::Process<Cmd("publish")>(Arg aArgs[])
/**
* @cli netdata publish dnssrp anycast
* @code
* netdata publish dnssrp anycast 1
* netdata publish dnssrp anycast 1 1
* Done
* @endcode
* @cparam netdata publish dnssrp anycast @ca{seq-num}
* @cparam netdata publish dnssrp anycast @ca{seq-num} [@ca{version}]
* @par
* Publishes a DNS/SRP Service Anycast Address with a sequence number. Any current
* DNS/SRP Service entry being published from a previous `publish dnssrp{anycast|unicast}`
* Publishes a DNS/SRP Service Anycast Address with a sequence number and version. Any current
* DNS/SRP Service entry being published from a previous `publish dnssrp {anycast|unicast}`
* command is removed and replaced with the new arguments.
* @par
* `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE` must be enabled.
* @csa{netdata publish dnssrp unicast (addr,port)}
* @csa{netdata publish dnssrp unicast (addr,port,version)}
* @csa{netdata publish dnssrp unicast (mle)}
* @sa otNetDataPublishDnsSrpServiceAnycast
* @endcli
@@ -262,55 +262,83 @@ template <> otError NetworkData::Process<Cmd("publish")>(Arg aArgs[])
if (aArgs[1] == "anycast")
{
uint8_t sequenceNumber;
uint8_t version = 0;
SuccessOrExit(error = aArgs[2].ParseAsUint8(sequenceNumber));
otNetDataPublishDnsSrpServiceAnycast(GetInstancePtr(), sequenceNumber);
if (!aArgs[3].IsEmpty())
{
SuccessOrExit(error = aArgs[3].ParseAsUint8(version));
VerifyOrExit(aArgs[4].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
}
otNetDataPublishDnsSrpServiceAnycast(GetInstancePtr(), sequenceNumber, version);
ExitNow();
}
if (aArgs[1] == "unicast")
{
otIp6Address address;
bool hasAddress = false;
uint16_t port;
uint8_t version = 0;
aArgs += 2;
if (aArgs->ParseAsIp6Address(address) == kErrorNone)
{
hasAddress = true;
aArgs++;
}
SuccessOrExit(error = aArgs->ParseAsUint16(port));
aArgs++;
if (!aArgs->IsEmpty())
{
SuccessOrExit(error = aArgs->ParseAsUint8(version));
aArgs++;
}
VerifyOrExit(aArgs->IsEmpty(), error = kErrorInvalidArgs);
/**
* @cli netdata publish dnssrp unicast (mle)
* @code
* netdata publish dnssrp unicast 50152
* netdata publish dnssrp unicast 50152 1
* Done
* @endcode
* @cparam netdata publish dnssrp unicast @ca{port}
* @cparam netdata publish dnssrp unicast @ca{port} [@ca{version}]
* @par
* Publishes the device's Mesh-Local EID with a port number. MLE and port information is
* included in the Server TLV data. To use a different Unicast address, use the
* `netdata publish dnssrp unicast (addr,port)` command.
* Publishes the device's Mesh-Local EID with a port number and given version. MLE, port and version
* information is included in the Server TLV data. To use a different Unicast address, use the
* `netdata publish dnssrp unicast (addr,port,version)` command.
* @par
* Any current DNS/SRP Service entry being published from a previous
* `publish dnssrp{anycast|unicast}` command is removed and replaced with the new arguments.
* `publish dnssrp {anycast|unicast}` command is removed and replaced with the new arguments.
* @par
* `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE` must be enabled.
* @csa{netdata publish dnssrp unicast (addr,port)}
* @csa{netdata publish dnssrp unicast (addr,port,version)}
* @csa{netdata publish dnssrp anycast}
* @sa otNetDataPublishDnsSrpServiceUnicastMeshLocalEid
*/
if (aArgs[3].IsEmpty())
if (!hasAddress)
{
SuccessOrExit(error = aArgs[2].ParseAsUint16(port));
otNetDataPublishDnsSrpServiceUnicastMeshLocalEid(GetInstancePtr(), port);
otNetDataPublishDnsSrpServiceUnicastMeshLocalEid(GetInstancePtr(), port, version);
ExitNow();
}
/**
* @cli netdata publish dnssrp unicast (addr,port)
* @cli netdata publish dnssrp unicast (addr,port,version)
* @code
* netdata publish dnssrp unicast fd00::1234 51525
* netdata publish dnssrp unicast fd00::1234 51525 1
* Done
* @endcode
* @cparam netdata publish dnssrp unicast @ca{address} @ca{port}
* @cparam netdata publish dnssrp unicast @ca{address} @ca{port} [@ca{version}]
* @par
* Publishes a DNS/SRP Service Unicast Address with an address and port number. The address
* and port information is included in Service TLV data. Any current DNS/SRP Service entry being
* published from a previous `publish dnssrp{anycast|unicast}` command is removed and replaced
* Publishes a DNS/SRP Service Unicast Address with an address and port and version number. The address,
* port, and version information is included in Service TLV data. Any current DNS/SRP Service entry being
* published from a previous `publish dnssrp {anycast|unicast}` command is removed and replaced
* with the new arguments.
* @par
* `OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE` must be enabled.
@@ -318,9 +346,7 @@ template <> otError NetworkData::Process<Cmd("publish")>(Arg aArgs[])
* @csa{netdata publish dnssrp anycast}
* @sa otNetDataPublishDnsSrpServiceUnicast
*/
SuccessOrExit(error = aArgs[2].ParseAsIp6Address(address));
SuccessOrExit(error = aArgs[3].ParseAsUint16(port));
otNetDataPublishDnsSrpServiceUnicast(GetInstancePtr(), &address, port);
otNetDataPublishDnsSrpServiceUnicast(GetInstancePtr(), &address, port, version);
ExitNow();
}
}
+10 -6
View File
@@ -41,19 +41,23 @@ using namespace ot;
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
void otNetDataPublishDnsSrpServiceAnycast(otInstance *aInstance, uint8_t aSequenceNumber)
void otNetDataPublishDnsSrpServiceAnycast(otInstance *aInstance, uint8_t aSequenceNumber, uint8_t aVersion)
{
AsCoreType(aInstance).Get<NetworkData::Publisher>().PublishDnsSrpServiceAnycast(aSequenceNumber);
AsCoreType(aInstance).Get<NetworkData::Publisher>().PublishDnsSrpServiceAnycast(aSequenceNumber, aVersion);
}
void otNetDataPublishDnsSrpServiceUnicast(otInstance *aInstance, const otIp6Address *aAddress, uint16_t aPort)
void otNetDataPublishDnsSrpServiceUnicast(otInstance *aInstance,
const otIp6Address *aAddress,
uint16_t aPort,
uint8_t aVersion)
{
AsCoreType(aInstance).Get<NetworkData::Publisher>().PublishDnsSrpServiceUnicast(AsCoreType(aAddress), aPort);
AsCoreType(aInstance).Get<NetworkData::Publisher>().PublishDnsSrpServiceUnicast(AsCoreType(aAddress), aPort,
aVersion);
}
void otNetDataPublishDnsSrpServiceUnicastMeshLocalEid(otInstance *aInstance, uint16_t aPort)
void otNetDataPublishDnsSrpServiceUnicastMeshLocalEid(otInstance *aInstance, uint16_t aPort, uint8_t aVersion)
{
AsCoreType(aInstance).Get<NetworkData::Publisher>().PublishDnsSrpServiceUnicast(aPort);
AsCoreType(aInstance).Get<NetworkData::Publisher>().PublishDnsSrpServiceUnicast(aPort, aVersion);
}
bool otNetDataIsDnsSrpServiceAdded(otInstance *aInstance)
+11 -2
View File
@@ -2412,6 +2412,8 @@ Error Client::SelectUnicastEntry(DnsSrpUnicastType aType, DnsSrpUnicastInfo &aIn
while (Get<NetworkData::Service::Manager>().GetNextDnsSrpUnicastInfo(iterator, aType, unicastInfo) == kErrorNone)
{
bool preferNewEntry;
if (mAutoStart.HasSelectedServer() && (GetServerAddress() == unicastInfo.mSockAddr))
{
aInfo = unicastInfo;
@@ -2431,10 +2433,17 @@ Error Client::SelectUnicastEntry(DnsSrpUnicastType aType, DnsSrpUnicastInfo &aIn
ExitNow();
}
#endif
// Prefer the server with higher version number, if equal
// then pick the one with numerically smaller IPv6 address.
// Prefer the numerically lowest server address
preferNewEntry = (error == kErrorNotFound) || (unicastInfo.mVersion > aInfo.mVersion);
if ((error == kErrorNotFound) || (unicastInfo.mSockAddr.GetAddress() < aInfo.mSockAddr.GetAddress()))
if (!preferNewEntry && (unicastInfo.mVersion == aInfo.mVersion))
{
preferNewEntry = (unicastInfo.mSockAddr.GetAddress() < aInfo.mSockAddr.GetAddress());
}
if (preferNewEntry)
{
aInfo = unicastInfo;
error = kErrorNone;
+2 -2
View File
@@ -149,12 +149,12 @@ void Server::Enable(void)
{
case kAddressModeUnicast:
SelectPort();
Get<NetworkData::Publisher>().PublishDnsSrpServiceUnicast(mPort);
Get<NetworkData::Publisher>().PublishDnsSrpServiceUnicast(mPort, kSrpVersion);
break;
case kAddressModeAnycast:
mPort = kAnycastAddressModePort;
Get<NetworkData::Publisher>().PublishDnsSrpServiceAnycast(mAnycastSequenceNumber);
Get<NetworkData::Publisher>().PublishDnsSrpServiceAnycast(mAnycastSequenceNumber, kSrpVersion);
break;
}
+2
View File
@@ -832,6 +832,8 @@ public:
void HandleServiceUpdateResult(ServiceUpdateId aId, Error aError);
private:
static constexpr uint8_t kSrpVersion = 0;
static constexpr uint16_t kUdpPayloadSize = Ip6::kMaxDatagramLength - sizeof(Ip6::Udp::Header);
static constexpr uint32_t kDefaultMinLease = 30; // 30 seconds.
+41 -27
View File
@@ -490,22 +490,23 @@ const char *Publisher::Entry::StateToString(State aState)
Publisher::DnsSrpServiceEntry::DnsSrpServiceEntry(Instance &aInstance) { Init(aInstance); }
void Publisher::DnsSrpServiceEntry::PublishAnycast(uint8_t aSequenceNumber)
void Publisher::DnsSrpServiceEntry::PublishAnycast(uint8_t aSequenceNumber, uint8_t aVersion)
{
LogInfo("Publishing DNS/SRP service anycast (seq-num:%d)", aSequenceNumber);
Publish(Info::InfoAnycast(aSequenceNumber));
LogInfo("Publishing DNS/SRP service anycast (seq-num:%u, ver:%u)", aSequenceNumber, aVersion);
Publish(Info::InfoAnycast(aSequenceNumber, aVersion));
}
void Publisher::DnsSrpServiceEntry::PublishUnicast(const Ip6::Address &aAddress, uint16_t aPort)
void Publisher::DnsSrpServiceEntry::PublishUnicast(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion)
{
LogInfo("Publishing DNS/SRP service unicast (%s, port:%d)", aAddress.ToString().AsCString(), aPort);
Publish(Info::InfoUnicast(kTypeUnicast, aAddress, aPort));
LogInfo("Publishing DNS/SRP service unicast (%s, port:%u, ver:%u)", aAddress.ToString().AsCString(), aPort,
aVersion);
Publish(Info::InfoUnicast(kTypeUnicast, aAddress, aPort, aVersion));
}
void Publisher::DnsSrpServiceEntry::PublishUnicast(uint16_t aPort)
void Publisher::DnsSrpServiceEntry::PublishUnicast(uint16_t aPort, uint8_t aVersion)
{
LogInfo("Publishing DNS/SRP service unicast (ml-eid, port:%d)", aPort);
Publish(Info::InfoUnicast(kTypeUnicastMeshLocalEid, Get<Mle::Mle>().GetMeshLocalEid(), aPort));
LogInfo("Publishing DNS/SRP service unicast (ml-eid, port:%u, ver:%u)", aPort, aVersion);
Publish(Info::InfoUnicast(kTypeUnicastMeshLocalEid, Get<Mle::Mle>().GetMeshLocalEid(), aPort, aVersion));
}
void Publisher::DnsSrpServiceEntry::Publish(const Info &aInfo)
@@ -568,17 +569,17 @@ void Publisher::DnsSrpServiceEntry::Add(void)
switch (GetType())
{
case kTypeAnycast:
SuccessOrExit(Get<Service::Manager>().AddDnsSrpAnycastService(mInfo.GetSequenceNumber()));
SuccessOrExit(Get<Service::Manager>().AddDnsSrpAnycastService(mInfo.GetSequenceNumber(), mInfo.GetVersion()));
break;
case kTypeUnicast:
SuccessOrExit(
Get<Service::Manager>().AddDnsSrpUnicastServiceWithAddrInServiceData(mInfo.GetAddress(), mInfo.GetPort()));
SuccessOrExit(Get<Service::Manager>().AddDnsSrpUnicastServiceWithAddrInServiceData(
mInfo.GetAddress(), mInfo.GetPort(), mInfo.GetVersion()));
break;
case kTypeUnicastMeshLocalEid:
SuccessOrExit(
Get<Service::Manager>().AddDnsSrpUnicastServiceWithAddrInServerData(mInfo.GetAddress(), mInfo.GetPort()));
SuccessOrExit(Get<Service::Manager>().AddDnsSrpUnicastServiceWithAddrInServerData(
mInfo.GetAddress(), mInfo.GetPort(), mInfo.GetVersion()));
break;
}
@@ -603,8 +604,8 @@ void Publisher::DnsSrpServiceEntry::Remove(State aNextState)
break;
case kTypeUnicast:
SuccessOrExit(Get<Service::Manager>().RemoveDnsSrpUnicastServiceWithAddrInServiceData(mInfo.GetAddress(),
mInfo.GetPort()));
SuccessOrExit(Get<Service::Manager>().RemoveDnsSrpUnicastServiceWithAddrInServiceData(
mInfo.GetAddress(), mInfo.GetPort(), mInfo.GetVersion()));
break;
case kTypeUnicastMeshLocalEid:
@@ -683,19 +684,22 @@ void Publisher::DnsSrpServiceEntry::CountAnycastEntries(uint8_t &aNumEntries, ui
{
// Count the number of matching "DNS/SRP Anycast" service entries
// in the Network Data (the match requires the entry to use same
// "sequence number" value). We prefer the entries associated with
// smaller RLCO16.
// "sequence number" value and same or higher version value). An
// entry with higher version number is preferred. If versions
// are equal then the associated RLOC16 values are used
// (routers are preferred over end-devices. If same type, then
// the smaller RLOC16 value is preferred).
Service::Manager::Iterator iterator;
Service::DnsSrpAnycastInfo anycastInfo;
while (Get<Service::Manager>().GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNone)
{
if (anycastInfo.mSequenceNumber == mInfo.GetSequenceNumber())
if (anycastInfo.mSequenceNumber == mInfo.GetSequenceNumber() && (anycastInfo.mVersion >= mInfo.GetVersion()))
{
aNumEntries++;
if (IsPreferred(anycastInfo.mRloc16))
if ((anycastInfo.mVersion > mInfo.GetVersion()) || IsPreferred(anycastInfo.mRloc16))
{
aNumPreferredEntries++;
}
@@ -716,17 +720,25 @@ void Publisher::DnsSrpServiceEntry::CountUnicastEntries(Service::DnsSrpUnicastTy
uint8_t &aNumPreferredEntries) const
{
// Count the number of DNS/SRP unicast entries in the Network Data.
// Only entries with the same or higher version number are considered.
// An entry with higher version is preferred. If versions are equal
// then the associated RLOC16 values are used (routers are preferred
// over end-devices. If same type, then the smaller RLOC16 value is
// preferred).
Service::Manager::Iterator iterator;
Service::DnsSrpUnicastInfo unicastInfo;
while (Get<Service::Manager>().GetNextDnsSrpUnicastInfo(iterator, aType, unicastInfo) == kErrorNone)
{
aNumEntries++;
if (IsPreferred(unicastInfo.mRloc16))
if (unicastInfo.mVersion >= mInfo.GetVersion())
{
aNumPreferredEntries++;
aNumEntries++;
if ((unicastInfo.mVersion > mInfo.GetVersion()) || IsPreferred(unicastInfo.mRloc16))
{
aNumPreferredEntries++;
}
}
}
}
@@ -743,9 +755,10 @@ bool Publisher::DnsSrpServiceEntry::HasAnyServiceDataUnicastEntry(void) const
//---------------------------------------------------------------------------------------------------------------------
// Publisher::DnsSrpServiceEntry::Info
Publisher::DnsSrpServiceEntry::Info::Info(Type aType, uint16_t aPortOrSeqNumber, const Ip6::Address *aAddress)
: mPortOrSeqNumber(aPortOrSeqNumber)
, mType(aType)
Publisher::DnsSrpServiceEntry::Info::Info(Type aType,
uint16_t aPortOrSeqNumber,
uint8_t aVersion,
const Ip6::Address *aAddress)
{
// It is important to `Clear()` the object since we compare all
// bytes using overload of operator `==`.
@@ -754,6 +767,7 @@ Publisher::DnsSrpServiceEntry::Info::Info(Type aType, uint16_t aPortOrSeqNumber,
mType = aType;
mPortOrSeqNumber = aPortOrSeqNumber;
mVersion = aVersion;
if (aAddress != nullptr)
{
+25 -11
View File
@@ -131,8 +131,12 @@ public:
* (from earlier call to any of `PublishDnsSrpService{Type}()` methods).
*
* @param[in] aSequenceNumber The sequence number of DNS/SRP Anycast Service.
* @param[in] aVersion The version number of DNS/SRP service.
*/
void PublishDnsSrpServiceAnycast(uint8_t aSequenceNumber) { mDnsSrpServiceEntry.PublishAnycast(aSequenceNumber); }
void PublishDnsSrpServiceAnycast(uint8_t aSequenceNumber, uint8_t aVersion)
{
mDnsSrpServiceEntry.PublishAnycast(aSequenceNumber, aVersion);
}
/**
* Requests "DNS/SRP Service Unicast Address" to be published in the Thread Network Data.
@@ -145,10 +149,11 @@ public:
*
* @param[in] aAddress The DNS/SRP server address to publish.
* @param[in] aPort The SRP server port number to publish.
* @param[in] aVersion The SRP server version to publish.
*/
void PublishDnsSrpServiceUnicast(const Ip6::Address &aAddress, uint16_t aPort)
void PublishDnsSrpServiceUnicast(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion)
{
mDnsSrpServiceEntry.PublishUnicast(aAddress, aPort);
mDnsSrpServiceEntry.PublishUnicast(aAddress, aPort, aVersion);
}
/**
@@ -162,8 +167,12 @@ public:
* in the Server TLV data.
*
* @param[in] aPort The SRP server port number to publish.
* @param[in] aVersion The SRP server version to publish.
*/
void PublishDnsSrpServiceUnicast(uint16_t aPort) { mDnsSrpServiceEntry.PublishUnicast(aPort); }
void PublishDnsSrpServiceUnicast(uint16_t aPort, uint8_t aVersion)
{
mDnsSrpServiceEntry.PublishUnicast(aPort, aVersion);
}
/**
* Indicates whether or not currently the "DNS/SRP Service" entry is added to the Thread Network Data.
@@ -365,9 +374,9 @@ private:
public:
explicit DnsSrpServiceEntry(Instance &aInstance);
void SetCallback(DnsSrpServiceCallback aCallback, void *aContext) { mCallback.Set(aCallback, aContext); }
void PublishAnycast(uint8_t aSequenceNumber);
void PublishUnicast(const Ip6::Address &aAddress, uint16_t aPort);
void PublishUnicast(uint16_t aPort);
void PublishAnycast(uint8_t aSequenceNumber, uint8_t aVersion);
void PublishUnicast(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion);
void PublishUnicast(uint16_t aPort, uint8_t aVersion);
void Unpublish(void);
void HandleTimer(void) { Entry::HandleTimer(); }
void HandleNotifierEvents(Events aEvents);
@@ -393,20 +402,25 @@ private:
Type GetType(void) const { return mType; }
uint8_t GetSequenceNumber(void) const { return static_cast<uint8_t>(mPortOrSeqNumber); }
uint16_t GetPort(void) const { return mPortOrSeqNumber; }
uint8_t GetVersion(void) const { return mVersion; }
const Ip6::Address &GetAddress(void) const { return mAddress; }
void SetAddress(const Ip6::Address &aAddress) { mAddress = aAddress; }
static Info InfoAnycast(uint8_t aSequenceNumber) { return Info(kTypeAnycast, aSequenceNumber); }
static Info InfoUnicast(Type aType, const Ip6::Address &aAddress, uint16_t aPort)
static Info InfoAnycast(uint8_t aSequenceNumber, uint8_t aVersion)
{
return Info(aType, aPort, &aAddress);
return Info(kTypeAnycast, aSequenceNumber, aVersion);
}
static Info InfoUnicast(Type aType, const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion)
{
return Info(aType, aPort, aVersion, &aAddress);
}
private:
Info(Type aType, uint16_t aPortOrSeqNumber, const Ip6::Address *aAddress = nullptr);
Info(Type aType, uint16_t aPortOrSeqNumber, uint8_t aVersion, const Ip6::Address *aAddress = nullptr);
Ip6::Address mAddress;
uint16_t mPortOrSeqNumber;
uint8_t mVersion;
Type mType;
};
+57 -31
View File
@@ -41,6 +41,13 @@ namespace Service {
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
Error Manager::AddDnsSrpAnycastService(uint8_t aSequenceNumber, uint8_t aVersion)
{
DnsSrpAnycastServiceData anycastData(aSequenceNumber);
return (aVersion == 0) ? AddService(anycastData) : AddService(anycastData, aVersion);
}
Error Manager::AddService(const void *aServiceData,
uint8_t aServiceDataLength,
const void *aServerData,
@@ -163,16 +170,19 @@ Error Manager::GetNextDnsSrpAnycastInfo(Iterator &aIterator, DnsSrpAnycastInfo &
if (IterateToNextServer(aIterator) == kErrorNone)
{
aIterator.mServiceTlv->GetServiceData(serviceData);
uint8_t dataLength = aIterator.mServiceTlv->GetServiceDataLength();
if (serviceData.GetLength() >= sizeof(DnsSrpAnycastServiceData))
if (dataLength >= sizeof(DnsSrpAnycastServiceData))
{
const DnsSrpAnycastServiceData *dnsServiceData =
reinterpret_cast<const DnsSrpAnycastServiceData *>(serviceData.GetBytes());
const DnsSrpAnycastServiceData *anycastData =
reinterpret_cast<const DnsSrpAnycastServiceData *>(aIterator.mServiceTlv->GetServiceData());
Get<Mle::Mle>().GetServiceAloc(aIterator.mServiceTlv->GetServiceId(), aInfo.mAnycastAddress);
aInfo.mSequenceNumber = dnsServiceData->GetSequenceNumber();
aInfo.mSequenceNumber = anycastData->GetSequenceNumber();
aInfo.mRloc16 = aIterator.mServerSubTlv->GetServer16();
aInfo.mVersion = (aIterator.mServerSubTlv->GetServerDataLength() >= sizeof(uint8_t))
? *aIterator.mServerSubTlv->GetServerData()
: 0;
ExitNow();
}
}
@@ -257,6 +267,34 @@ Error Manager::FindPreferredDnsSrpAnycastInfo(DnsSrpAnycastInfo &aInfo) const
}
}
// Determine the minimum version supported among all entries
// matching the selected `aInfo.mSequenceNumber`.
iterator.Reset();
while (GetNextDnsSrpAnycastInfo(iterator, info) == kErrorNone)
{
if (info.mSequenceNumber == aInfo.mSequenceNumber)
{
aInfo.mVersion = Min(aInfo.mVersion, info.mVersion);
}
}
exit:
return error;
}
Error Manager::DnsSrpUnicast::AddrData::ParseFrom(const uint8_t *aData, uint8_t aLength, DnsSrpUnicastInfo &aInfo)
{
Error error = kErrorNone;
const AddrData *addrData = reinterpret_cast<const AddrData *>(aData);
VerifyOrExit(aLength >= kMinLength, error = kErrorParse);
aInfo.mSockAddr.SetAddress(addrData->GetAddress());
aInfo.mSockAddr.SetPort(addrData->GetPort());
aInfo.mVersion = (aLength >= sizeof(AddrData)) ? addrData->GetVersion() : 0;
exit:
return error;
}
@@ -274,26 +312,21 @@ Error Manager::GetNextDnsSrpUnicastInfo(Iterator &aIterator, DnsSrpUnicastType a
while (IterateToNextServer(aIterator) == kErrorNone)
{
ServerData data;
aInfo.mRloc16 = aIterator.mServerSubTlv->GetServer16();
if (aType == kAddrInServiceData)
{
const DnsSrpUnicast::ServiceData *dnsServiceData;
if (aIterator.mServiceTlv->GetServiceDataLength() < sizeof(DnsSrpUnicast::ServiceData))
if (DnsSrpUnicast::ServiceData::ParseFrom(*aIterator.mServiceTlv, aInfo) == kErrorNone)
{
// Break from `while(IterateToNextServer())` loop
// to skip over the Service TLV and all its
// sub-TLVs and go to the next one.
break;
ExitNow();
}
aIterator.mServiceTlv->GetServiceData(serviceData);
dnsServiceData = reinterpret_cast<const DnsSrpUnicast::ServiceData *>(serviceData.GetBytes());
aInfo.mSockAddr.SetAddress(dnsServiceData->GetAddress());
aInfo.mSockAddr.SetPort(dnsServiceData->GetPort());
aInfo.mRloc16 = aIterator.mServerSubTlv->GetServer16();
ExitNow();
// If Service Data does not contain address info, we
// break from `while (IterateToNextServer())` loop
// to skip over the entire Service TLV and all its
// sub-TLVs and go to the next one.
break;
}
// `aType` is `kAddrInServerData`.
@@ -302,28 +335,21 @@ Error Manager::GetNextDnsSrpUnicastInfo(Iterator &aIterator, DnsSrpUnicastType a
// (then we parse and return the info), or it can be
// empty (then we skip over it).
aIterator.mServerSubTlv->GetServerData(data);
if (data.GetLength() >= sizeof(DnsSrpUnicast::ServerData))
if (DnsSrpUnicast::ServerData::ParseFrom(*aIterator.mServerSubTlv, aInfo) == kErrorNone)
{
const DnsSrpUnicast::ServerData *serverData =
reinterpret_cast<const DnsSrpUnicast::ServerData *>(data.GetBytes());
aInfo.mSockAddr.SetAddress(serverData->GetAddress());
aInfo.mSockAddr.SetPort(serverData->GetPort());
aInfo.mRloc16 = aIterator.mServerSubTlv->GetServer16();
ExitNow();
}
if (data.GetLength() == sizeof(uint16_t))
if (aIterator.mServerSubTlv->GetServerDataLength() == sizeof(uint16_t))
{
// Handle the case where the server TLV data only
// contains a port number and use the RLOC as the
// IPv6 address.
aInfo.mSockAddr.GetAddress().SetToRoutingLocator(Get<Mle::Mle>().GetMeshLocalPrefix(),
aIterator.mServerSubTlv->GetServer16());
aInfo.mSockAddr.SetPort(BigEndian::ReadUint16(data.GetBytes()));
aInfo.mRloc16 = aIterator.mServerSubTlv->GetServer16();
aInfo.mSockAddr.SetPort(BigEndian::ReadUint16(aIterator.mServerSubTlv->GetServerData()));
aInfo.mVersion = 0;
ExitNow();
}
}
+96 -34
View File
@@ -59,6 +59,7 @@ struct DnsSrpAnycastInfo
{
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.
uint8_t mVersion; ///< Version number.
uint16_t mRloc16; ///< The RLOC16 of the entry.
};
@@ -77,6 +78,7 @@ enum DnsSrpUnicastType : uint8_t
struct DnsSrpUnicastInfo
{
Ip6::SockAddr mSockAddr; ///< The socket address (IPv6 address and port) of the DNS/SRP server.
uint8_t mVersion; ///< Version number.
uint16_t mRloc16; ///< The BR RLOC16 adding the entry.
};
@@ -132,14 +134,12 @@ public:
* Adds a DNS/SRP Anycast Service entry to the local Thread Network Data.
*
* @param[in] aSequenceNumber The anycast sequence number.
* @param[in] aVersion The version number
*
* @retval kErrorNone Successfully added the Service entry.
* @retval kErrorNoBufs Insufficient space to add the Service entry.
*/
Error AddDnsSrpAnycastService(uint8_t aSequenceNumber)
{
return AddService(DnsSrpAnycastServiceData(aSequenceNumber));
}
Error AddDnsSrpAnycastService(uint8_t aSequenceNumber, uint8_t aVersion);
/**
* Removes a DNS/SRP Anycast Service entry from local Thread Network Data.
@@ -159,13 +159,14 @@ public:
*
* @param[in] aAddress The unicast address.
* @param[in] aPort The port number.
* @param[in] aVersion The version.
*
* @retval kErrorNone Successfully added the Service entry.
* @retval kErrorNoBufs Insufficient space to add the Service entry.
*/
Error AddDnsSrpUnicastServiceWithAddrInServiceData(const Ip6::Address &aAddress, uint16_t aPort)
Error AddDnsSrpUnicastServiceWithAddrInServiceData(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion)
{
return AddService(DnsSrpUnicast::ServiceData(aAddress, aPort));
return AddService(DnsSrpUnicast::ServiceData(aAddress, aPort, aVersion));
}
/**
@@ -173,13 +174,16 @@ public:
*
* @param[in] aAddress The unicast address.
* @param[in] aPort The port number.
* @param[in] aVersion The version.
*
* @retval kErrorNone Successfully removed the Service entry.
* @retval kErrorNotFound Could not find the Service entry.
*/
Error RemoveDnsSrpUnicastServiceWithAddrInServiceData(const Ip6::Address &aAddress, uint16_t aPort)
Error RemoveDnsSrpUnicastServiceWithAddrInServiceData(const Ip6::Address &aAddress,
uint16_t aPort,
uint8_t aVersion)
{
return RemoveService(DnsSrpUnicast::ServiceData(aAddress, aPort));
return RemoveService(DnsSrpUnicast::ServiceData(aAddress, aPort, aVersion));
}
/**
@@ -187,13 +191,14 @@ public:
*
* @param[in] aAddress The unicast address.
* @param[in] aPort The port number.
* @param[in] aVersion The version.
*
* @retval kErrorNone Successfully added the Service entry.
* @retval kErrorNoBufs Insufficient space to add the Service entry.
*/
Error AddDnsSrpUnicastServiceWithAddrInServerData(const Ip6::Address &aAddress, uint16_t aPort)
Error AddDnsSrpUnicastServiceWithAddrInServerData(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion)
{
return AddService(kDnsSrpUnicastServiceNumber, DnsSrpUnicast::ServerData(aAddress, aPort));
return AddServiceWithNumber(kDnsSrpUnicastServiceNumber, DnsSrpUnicast::ServerData(aAddress, aPort, aVersion));
}
/**
@@ -217,8 +222,8 @@ public:
*/
Error AddBackboneRouterService(uint8_t aSequenceNumber, uint16_t aReregistrationDelay, uint32_t aMlrTimeout)
{
return AddService(kBackboneRouterServiceNumber,
BbrServerData(aSequenceNumber, aReregistrationDelay, aMlrTimeout));
return AddServiceWithNumber(kBackboneRouterServiceNumber,
BbrServerData(aSequenceNumber, aReregistrationDelay, aMlrTimeout));
}
/**
@@ -275,6 +280,9 @@ public:
* The preferred entry is determined based on the sequence number value where a larger value (in the sense
* specified by Serial Number Arithmetic logic in RFC-1982) is considered more recent and therefore preferred.
*
* When successfully found, the `aInfo.mVersion` is set to the minimum version among all the entries matching the
* same sequence number as the selected `aInfo.mSequenceNumber`.
*
* @param[out] aInfo A reference to `DnsSrpAnycastInfo` to return the info.
*
* @retval kErrorNone Successfully found the preferred info. @p aInfo is updated.
@@ -314,6 +322,7 @@ private:
}
uint8_t GetSequenceNumber(void) const { return mSequenceNumber; }
uint8_t GetLength(void) const { return sizeof(DnsSrpAnycastServiceData); }
private:
uint8_t mServiceNumber;
@@ -324,44 +333,89 @@ private:
{
public:
OT_TOOL_PACKED_BEGIN
struct ServiceData
class AddrData
{
public:
explicit ServiceData(const Ip6::Address &aAddress, uint16_t aPort)
: mServiceNumber(kDnsSrpUnicastServiceNumber)
, mAddress(aAddress)
static constexpr uint8_t kMinLength = sizeof(Ip6::Address) + sizeof(uint16_t); // Address and port.
AddrData(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion)
: mAddress(aAddress)
, mPort(BigEndian::HostSwap16(aPort))
, mVersion(aVersion)
{
}
uint8_t GetLength(void) const { return (mVersion == 0) ? kMinLength : sizeof(AddrData); }
const Ip6::Address &GetAddress(void) const { return mAddress; }
uint16_t GetPort(void) const { return BigEndian::HostSwap16(mPort); }
uint8_t GetVersion(void) const { return mVersion; }
static Error ParseFrom(const uint8_t *aData, uint8_t aLength, DnsSrpUnicastInfo &aInfo);
private:
Ip6::Address mAddress;
uint16_t mPort;
uint8_t mVersion;
} OT_TOOL_PACKED_END;
static_assert(AddrData::kMinLength + sizeof(uint8_t) == sizeof(AddrData),
"Update all methods/constants if adding new (optional) fields to `AddrData`.");
OT_TOOL_PACKED_BEGIN
class ServiceData
{
public:
static constexpr uint8_t kMinLength = sizeof(uint8_t) + AddrData::kMinLength;
ServiceData(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion)
: mServiceNumber(kDnsSrpUnicastServiceNumber)
, mAddrData(aAddress, aPort, aVersion)
{
OT_UNUSED_VARIABLE(mServiceNumber);
}
const Ip6::Address &GetAddress(void) const { return mAddress; }
uint16_t GetPort(void) const { return BigEndian::HostSwap16(mPort); }
uint8_t GetLength(void) const { return sizeof(uint8_t) + mAddrData.GetLength(); }
static Error ParseFrom(const ServiceTlv &aServiceTlv, DnsSrpUnicastInfo &aInfo)
{
// Skip over `mServiceNumber` field (`uint8_t`)`
return AddrData::ParseFrom(aServiceTlv.GetServiceData() + sizeof(uint8_t),
aServiceTlv.GetServiceDataLength() - sizeof(uint8_t), aInfo);
}
private:
uint8_t mServiceNumber;
Ip6::Address mAddress;
uint16_t mPort;
uint8_t mServiceNumber;
AddrData mAddrData;
} OT_TOOL_PACKED_END;
static_assert(ServiceData::kMinLength + sizeof(uint8_t) == sizeof(ServiceData),
"Update all methods/constants if adding new (optional) fields to `ServiceData`.");
OT_TOOL_PACKED_BEGIN
class ServerData
{
public:
ServerData(const Ip6::Address &aAddress, uint16_t aPort)
: mAddress(aAddress)
, mPort(BigEndian::HostSwap16(aPort))
static constexpr uint8_t kMinLength = AddrData::kMinLength;
ServerData(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion)
: mAddrData(aAddress, aPort, aVersion)
{
}
const Ip6::Address &GetAddress(void) const { return mAddress; }
uint16_t GetPort(void) const { return BigEndian::HostSwap16(mPort); }
uint8_t GetLength(void) const { return mAddrData.GetLength(); }
static Error ParseFrom(const ServerTlv &aServerTlv, DnsSrpUnicastInfo &aInfo)
{
return AddrData::ParseFrom(aServerTlv.GetServerData(), aServerTlv.GetServerDataLength(), aInfo);
}
private:
Ip6::Address mAddress;
uint16_t mPort;
AddrData mAddrData;
} OT_TOOL_PACKED_END;
static_assert(ServerData::kMinLength + sizeof(uint8_t) == sizeof(ServerData),
"Update all methods/constants if adding new (optional) fields to `ServerData`.");
DnsSrpUnicast(void) = delete;
};
@@ -380,6 +434,7 @@ private:
uint8_t GetSequenceNumber(void) const { return mSequenceNumber; }
uint16_t GetReregistrationDelay(void) const { return BigEndian::HostSwap16(mReregDelay); }
uint32_t GetMlrTimeout(void) const { return BigEndian::HostSwap32(mMlrTimeout); }
uint8_t GetLength(void) const { return sizeof(BbrServerData); }
private:
uint8_t mSequenceNumber;
@@ -391,22 +446,29 @@ private:
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
template <typename ServiceDataType> Error AddService(const ServiceDataType &aServiceData)
{
return AddService(&aServiceData, sizeof(ServiceDataType), nullptr, 0);
return AddService(&aServiceData, aServiceData.GetLength(), nullptr, 0);
}
template <typename ServerDataType> Error AddService(uint8_t aServiceNumber, const ServerDataType &aServerData)
template <typename ServerDataType>
Error AddServiceWithNumber(uint8_t aServiceNumber, const ServerDataType &aServerData)
{
return AddService(&aServiceNumber, sizeof(uint8_t), &aServerData, sizeof(ServerDataType));
return AddService(&aServiceNumber, sizeof(uint8_t), &aServerData, aServerData.GetLength());
}
template <typename ServiceDataType, typename ServerDataType>
Error AddService(const ServiceDataType &aServiceData, const ServerDataType &aServerData)
{
return AddService(&aServiceData, aServiceData.GetLength(), &aServerData, sizeof(ServerDataType));
}
Error AddService(const void *aServiceData,
uint8_t aServiceDataLength,
const void *aServerData = nullptr,
uint8_t aServerDataLength = 0);
const void *aServerData,
uint8_t aServerDataLength);
template <typename ServiceDataType> Error RemoveService(const ServiceDataType &aServiceData)
{
return RemoveService(&aServiceData, sizeof(ServiceDataType));
return RemoveService(&aServiceData, aServiceData.GetLength());
}
Error RemoveService(uint8_t aServiceNumber) { return RemoveService(&aServiceNumber, sizeof(uint8_t)); }
+19 -8
View File
@@ -1244,6 +1244,17 @@ public:
aServiceData.Init(GetServiceData(), GetServiceDataLength());
}
/**
* Gets the Service Data bytes.
*
* @returns A pointer to start of the Service Data bytes.
*/
const uint8_t *GetServiceData(void) const
{
return (IsThreadEnterprise() ? &mShared.mServiceDataLengthThreadEnterprise : &mServiceDataLength) +
sizeof(uint8_t);
}
/**
* Gets Service Data length.
*
@@ -1306,12 +1317,6 @@ public:
private:
bool IsThreadEnterprise(void) const { return (mFlagsServiceId & kThreadEnterpriseFlag) != 0; }
const uint8_t *GetServiceData(void) const
{
return (IsThreadEnterprise() ? &mShared.mServiceDataLengthThreadEnterprise : &mServiceDataLength) +
sizeof(uint8_t);
}
uint8_t GetFieldsLength(void) const
{
// Returns the length of TLV value's common fields (flags, enterprise
@@ -1392,6 +1397,13 @@ public:
*/
void GetServerData(ServerData &aServerData) const { aServerData.Init(GetServerData(), GetServerDataLength()); }
/**
* Gets the Server Data bytes.
*
* @returns A pointer to start of the Server Data bytes.
*/
const uint8_t *GetServerData(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
/**
* Returns the Server Data length in bytes.
*
@@ -1424,8 +1436,7 @@ public:
static uint16_t CalculateSize(uint8_t aServerDataLength) { return sizeof(ServerTlv) + aServerDataLength; }
private:
const uint8_t *GetServerData(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
uint8_t *GetServerData(void) { return AsNonConst(AsConst(this)->GetServerData()); }
uint8_t *GetServerData(void) { return AsNonConst(AsConst(this)->GetServerData()); }
uint16_t mServer16;
} OT_TOOL_PACKED_END;
+6 -6
View File
@@ -2515,16 +2515,16 @@ class NodeImpl:
self.send_command('netdata register')
self._expect_done()
def netdata_publish_dnssrp_anycast(self, seqnum):
self.send_command(f'netdata publish dnssrp anycast {seqnum}')
def netdata_publish_dnssrp_anycast(self, seqnum, version=0):
self.send_command(f'netdata publish dnssrp anycast {seqnum} {version}')
self._expect_done()
def netdata_publish_dnssrp_unicast(self, address, port):
self.send_command(f'netdata publish dnssrp unicast {address} {port}')
def netdata_publish_dnssrp_unicast(self, address, port, version=0):
self.send_command(f'netdata publish dnssrp unicast {address} {port} {version}')
self._expect_done()
def netdata_publish_dnssrp_unicast_mleid(self, port):
self.send_command(f'netdata publish dnssrp unicast {port}')
def netdata_publish_dnssrp_unicast_mleid(self, port, version=0):
self.send_command(f'netdata publish dnssrp unicast {port} {version}')
self._expect_done()
def netdata_unpublish_dnssrp(self):
@@ -221,7 +221,7 @@ class NetDataPublisher(thread_cert.TestCase):
self.assertEqual(end_dev.get_state(), 'child')
#---------------------------------------------------------------------------------
# DNS/SRP anycast entries
# DNS/SRP anycast entries - equal version number
# Publish DNS/SRP anycast on leader and all routers (6 nodes).
@@ -263,7 +263,57 @@ class NetDataPublisher(thread_cert.TestCase):
self.verify_anycast_services(services)
#---------------------------------------------------------------------------------
# DNS/SRP service data unicast entries
# DNS/SRP anycast entries - different version numbers
# Publish DNS/SRP anycast on leader and all routers (6 nodes).
version = 0
leader.netdata_publish_dnssrp_anycast(ANYCAST_SEQ_NUM, version)
num = 1
for node in routers:
version += 1
node.netdata_publish_dnssrp_anycast(ANYCAST_SEQ_NUM, version)
num += 1
self.simulator.go(WAIT_TIME)
# Check all entries are present in the network data
services = leader.get_services()
self.assertEqual(len(services), min(num, DESIRED_NUM_DNSSRP_ANYCAST))
self.verify_anycast_services(services)
# Publish same entry with same version on all end-devices (5 nodes).
for node in end_devs:
node.netdata_publish_dnssrp_anycast(ANYCAST_SEQ_NUM, version)
num += 1
print(node.name)
self.simulator.go(WAIT_TIME)
# Check number of entries in the network data is limited
# to the desired number (8 entries). All new entries use
# higher version and should be preferred. Validate that
# the 'services' list contains the new services.
services = leader.get_services()
self.assertEqual(len(services), min(num, DESIRED_NUM_DNSSRP_ANYCAST))
self.verify_anycast_services(services)
node_rloc16 = node.get_addr16()
self.assertTrue(any(int(service[4], 16) == node_rloc16 for service in services))
# Unpublish the entry from nodes one by one starting from leader
# and check that number of entries is correct in each step.
for node in nodes:
node.netdata_unpublish_dnssrp()
self.simulator.go(WAIT_TIME)
num -= 1
services = leader.get_services()
self.assertEqual(len(services), min(num, DESIRED_NUM_DNSSRP_ANYCAST))
self.verify_anycast_services(services)
#---------------------------------------------------------------------------------
# DNS/SRP service data unicast entries - equal version number
num = 0
for node in routers:
@@ -295,7 +345,33 @@ class NetDataPublisher(thread_cert.TestCase):
self.assertEqual(node.srp_server_get_state(), 'disabled')
#---------------------------------------------------------------------------------
# DNS/SRP server data unicast entries
# DNS/SRP service data unicast entries - different version numbers
num = 0
for node in routers:
# Use `num` as version.
node.netdata_publish_dnssrp_unicast(DNSSRP_ADDRESS, DNSSRP_PORT, num)
self.simulator.go(WAIT_TIME)
num += 1
services = leader.get_services()
self.assertEqual(len(services), min(num, DESIRED_NUM_DNSSRP_UNICAST))
self.verify_unicast_services(services)
# The most recent service should win as it uses a higher version
# number. Validate that the 'services' list contains the service
# from this node by checking the service RLOC16.
node_rloc16 = node.get_addr16()
self.assertTrue(any(int(service[4], 16) == node_rloc16 for service in services))
for node in reversed(routers):
node.netdata_unpublish_dnssrp()
self.simulator.go(WAIT_TIME)
num -= 1
services = leader.get_services()
self.assertEqual(len(services), min(num, DESIRED_NUM_DNSSRP_UNICAST))
self.verify_unicast_services(services)
#---------------------------------------------------------------------------------
# DNS/SRP server data unicast entries - equal version number
num = 0
for node in routers:
@@ -325,6 +401,55 @@ class NetDataPublisher(thread_cert.TestCase):
node.srp_server_set_enabled(False)
self.assertEqual(node.srp_server_get_state(), 'disabled')
#---------------------------------------------------------------------------------
# DNS/SRP server data unicast entries - different version numbers
num = 0
for node in routers:
node.netdata_publish_dnssrp_unicast_mleid(DNSSRP_PORT, num)
self.simulator.go(WAIT_TIME)
num += 1
services = leader.get_services()
self.assertEqual(len(services), min(num, DESIRED_NUM_DNSSRP_UNICAST))
self.verify_unicast_services(services)
# The most recent service should win as it uses a higher version
# number. Validate that the 'services' list contains the service
# from this node by checking the service RLOC16.
node_rloc16 = node.get_addr16()
self.assertTrue(any(int(service[4], 16) == node_rloc16 for service in services))
for node in reversed(routers):
node.netdata_unpublish_dnssrp()
self.simulator.go(WAIT_TIME)
num -= 1
services = leader.get_services()
self.assertEqual(len(services), min(num, DESIRED_NUM_DNSSRP_UNICAST))
self.verify_unicast_services(services)
# Repeat the same test steps, but start with larger version
# numbers first.
num = 0
for node in routers:
node.netdata_publish_dnssrp_unicast_mleid(DNSSRP_PORT, 20 - num)
self.simulator.go(WAIT_TIME)
num += 1
services = leader.get_services()
self.assertEqual(len(services), min(num, DESIRED_NUM_DNSSRP_UNICAST))
self.verify_unicast_services(services)
# The service from first router should win as it uses the highest
# version number.
first_router_rloc16 = routers[0].get_addr16()
self.assertTrue(any(int(service[4], 16) == first_router_rloc16 for service in services))
for node in routers:
node.netdata_unpublish_dnssrp()
self.simulator.go(WAIT_TIME)
num -= 1
services = leader.get_services()
self.assertEqual(len(services), min(num, DESIRED_NUM_DNSSRP_UNICAST))
self.verify_unicast_services(services)
#---------------------------------------------------------------------------------
# DNS/SRP server data unicast vs anycast
+147 -76
View File
@@ -635,6 +635,7 @@ void TestNetworkDataDsnSrpServices(void)
{
uint16_t mAloc16;
uint8_t mSequenceNumber;
uint8_t mVersion;
uint16_t mRloc16;
bool Matches(Service::DnsSrpAnycastInfo aInfo) const
@@ -642,7 +643,8 @@ void TestNetworkDataDsnSrpServices(void)
VerifyOrQuit(aInfo.mAnycastAddress.GetIid().IsAnycastServiceLocator());
return (aInfo.mAnycastAddress.GetIid().GetLocator() == mAloc16) &&
(aInfo.mSequenceNumber == mSequenceNumber) && (aInfo.mRloc16 == mRloc16);
(aInfo.mSequenceNumber == mSequenceNumber) && (aInfo.mVersion == mVersion) &&
(aInfo.mRloc16 == mRloc16);
}
};
@@ -650,6 +652,7 @@ void TestNetworkDataDsnSrpServices(void)
{
const char *mAddress;
uint16_t mPort;
uint8_t mVersion;
uint16_t mRloc16;
bool Matches(const Service::DnsSrpUnicastInfo &aInfo) const
@@ -659,38 +662,50 @@ void TestNetworkDataDsnSrpServices(void)
SuccessOrQuit(sockAddr.GetAddress().FromString(mAddress));
sockAddr.SetPort(mPort);
return (aInfo.mSockAddr == sockAddr) && (aInfo.mRloc16 == mRloc16);
return (aInfo.mSockAddr == sockAddr) && (aInfo.mVersion == mVersion) && (aInfo.mRloc16 == mRloc16);
}
};
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, 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,
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x28, 0x00,
0x0b, 0x09, 0x81, 0x02, 0x5c, 0xff, 0x0d, 0x03, 0x6c, 0x00, 0x05,
0x0b, 0x09, 0x82, 0x03, 0x5c, 0x03, 0xaa, 0x0d, 0x02, 0x4c, 0x00,
0x0b, 0x36, 0x83, 0x14, 0x5d, 0xfd, 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0x00, 0x2d,
0x0e, 0xc6, 0x27, 0x55, 0x56, 0x18, 0xd9, 0x12, 0x34, 0x03, 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, 0x24, 0x84, 0x01, 0x5d, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x15, 0x4c, 0x00, 0xfd,
0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x01, 0x23, 0x45, 0x67, 0x89,
0xab, 0x00, 0x0e, 0x01, 0x0d, 0x04, 0x6c, 0x00, 0xcd, 0x12,
0x0b, 0x08, 0x84, 0x01, 0x5c, 0x0d, 0x02, 0x14, 0x01, 0x0d,
0x0b, 0x07, 0x83, 0x01, 0x5c, 0x0d, 0x02, 0x28, 0x00,
0x0b, 0x13, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x03, 0x12, 0x00, 0x07, 0x0d, 0x03, 0x12,
0x01, 0x06, 0x0d, 0x03, 0x16, 0x00, 0x07,
};
const AnycastEntry kAnycastEntries[] = {
{0xfc10, 0x02, 0x2800}, {0xfc11, 0xff, 0x6c00}, {0xfc12, 0x03, 0x4c00},
{0xfc13, 0xfe, 0x1200}, {0xfc13, 0xfe, 0x1201}, {0xfc13, 0xfe, 0x1600},
{0xfc10, 0x02, 0, 0x2800}, {0xfc11, 0xff, 5, 0x6c00}, {0xfc12, 0x03, 0, 0x4c00},
{0xfc13, 0xfe, 7, 0x1200}, {0xfc13, 0xfe, 6, 0x1201}, {0xfc13, 0xfe, 7, 0x1600},
};
const UnicastEntry kUnicastEntriesFromServerData[] = {
{"fd00:aabb:ccdd:eeff:11:2233:4455:6677", 0xabcd, 0x6c00},
{"fdde:ad00:beef:0:0:ff:fe00:2800", 0x5678, 0x2800},
{"fd00:1234:5678:9abc:def0:123:4567:89ab", 0x0e, 0x4c00},
{"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, 0x6c00},
{"fd00:aabb:ccdd:eeff:11:2233:4455:6677", 0xabcd, 0, 0x6c00},
{"fdde:ad00:beef:0:0:ff:fe00:2800", 0x5678, 0, 0x2800},
{"fd00:1234:5678:9abc:def0:123:4567:89ab", 0x0e, 1, 0x4c00},
{"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, 0, 0x6c00},
};
const UnicastEntry kUnicastEntriesFromServiceData[] = {
{"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 0x0000},
{"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 0x6c00},
{"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 0x2800},
{"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 3, 0x0000},
{"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 3, 0x6c00},
{"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 3, 0x2800},
};
const uint16_t kExpectedRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000, 0x1200, 0x1201, 0x1600, 0x1401};
@@ -733,8 +748,9 @@ void TestNetworkDataDsnSrpServices(void)
{
SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
printf("\nanycastInfo { %s, seq:%d, rlco16:%04x }", anycastInfo.mAnycastAddress.ToString().AsCString(),
anycastInfo.mSequenceNumber, anycastInfo.mRloc16);
printf("\nanycastInfo { %s, seq:%d, rlco16:%04x, version:%u }",
anycastInfo.mAnycastAddress.ToString().AsCString(), anycastInfo.mSequenceNumber, anycastInfo.mRloc16,
anycastInfo.mVersion);
VerifyOrQuit(entry.Matches(anycastInfo), "GetNextDnsSrpAnycastInfo() returned incorrect info");
}
@@ -746,8 +762,8 @@ void TestNetworkDataDsnSrpServices(void)
SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
printf("\n\nPreferred anycastInfo { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(),
anycastInfo.mSequenceNumber);
printf("\n\nPreferred anycastInfo { %s, seq:%d, version:%u }",
anycastInfo.mAnycastAddress.ToString().AsCString(), anycastInfo.mSequenceNumber, anycastInfo.mVersion);
VerifyOrQuit(kAnycastEntries[kPreferredAnycastEntryIndex].Matches(anycastInfo),
"FindPreferredDnsSrpAnycastInfo() returned invalid info");
@@ -813,6 +829,7 @@ void TestNetworkDataDsnSrpAnycastSeqNumSelection(void)
const uint8_t *mSeqNumbers;
uint8_t mSeqNumbersLength;
uint8_t mPreferredSeqNum;
uint8_t mPreferredVersion;
};
Instance *instance;
@@ -824,90 +841,99 @@ void TestNetworkDataDsnSrpAnycastSeqNumSelection(void)
VerifyOrQuit(instance != nullptr);
const uint8_t kNetworkData1[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x81, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x81, 0x0d, 0x02, 0x50, 0x01, // Service TLV
};
const uint8_t kSeqNumbers1[] = {1, 129};
const uint8_t kPreferredSeqNum1 = 129;
const uint8_t kPreferredVer1 = 0;
const uint8_t kNetworkData2[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x85, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x05, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x85, 0x0d, 0x02, 0x50, 0x00, // Service TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x05, 0x0d, 0x02, 0x50, 0x01, // Service TLV
};
const uint8_t kSeqNumbers2[] = {133, 5};
const uint8_t kPreferredSeqNum2 = 133;
const uint8_t kPreferredVer2 = 0;
const uint8_t kNetworkData3[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Service TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Service TLV
};
const uint8_t kSeqNumbers3[] = {1, 2, 255};
const uint8_t kPreferredSeqNum3 = 2;
const uint8_t kPreferredVer3 = 0;
const uint8_t kNetworkData4[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x00, // Service TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x01, // Service TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x02, // Service TLV
};
const uint8_t kSeqNumbers4[] = {10, 130, 250};
const uint8_t kPreferredSeqNum4 = 250;
const uint8_t kPreferredVer4 = 0;
const uint8_t kNetworkData5[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x00, // Service TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x01, // Service TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x02, // Service TLV
};
const uint8_t kSeqNumbers5[] = {130, 250, 10};
const uint8_t kPreferredSeqNum5 = 250;
const uint8_t kPreferredVer5 = 0;
const uint8_t kNetworkData6[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Service TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Service TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x02, // Service TLV
};
const uint8_t kSeqNumbers6[] = {250, 10, 130};
const uint8_t kPreferredSeqNum6 = 250;
const uint8_t kPreferredVer6 = 0;
const uint8_t kNetworkData7[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0x8A, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Service TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Service TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0x8A, 0x0d, 0x02, 0x50, 0x02, // Service TLV
};
const uint8_t kSeqNumbers7[] = {250, 10, 138};
const uint8_t kPreferredSeqNum7 = 250;
const uint8_t kPreferredVer7 = 0;
const uint8_t kNetworkData8[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Service TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Service TLV
0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Service TLV
};
const uint8_t kSeqNumbers8[] = {1, 2, 255, 254};
const uint8_t kPreferredSeqNum8 = 2;
const uint8_t kPreferredVer8 = 0;
const uint8_t kNetworkData9[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Service TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Service TLV
0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Service TLV
};
const uint8_t kSeqNumbers9[] = {1, 2, 255, 254};
const uint8_t kPreferredSeqNum9 = 2;
const uint8_t kPreferredVer9 = 0;
const uint8_t kNetworkData10[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
@@ -916,9 +942,10 @@ void TestNetworkDataDsnSrpAnycastSeqNumSelection(void)
};
const uint8_t kSeqNumbers10[] = {254, 2, 120, 1};
const uint8_t kPreferredSeqNum10 = 120;
const uint8_t kPreferredVer10 = 0;
const uint8_t kNetworkData11[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Service TLV
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0xf0, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
@@ -927,19 +954,61 @@ void TestNetworkDataDsnSrpAnycastSeqNumSelection(void)
};
const uint8_t kSeqNumbers11[] = {240, 2, 120, 1};
const uint8_t kPreferredSeqNum11 = 240;
const uint8_t kPreferredVer11 = 0;
const uint8_t kNetworkData12[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
0x0b, 0x09, 0x81, 0x02, 0x5c, 0x81, 0x0d, 0x03, 0x50, 0x01, 0x01, // Service TLV
};
const uint8_t kSeqNumbers12[] = {1, 129};
const uint8_t kPreferredSeqNum12 = 129;
const uint8_t kPreferredVer12 = 1;
const uint8_t kNetworkData13[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
0x0b, 0x0e, 0x81, 0x02, 0x5c, 0x81, // Service TLV
0x0d, 0x03, 0x50, 0x01, 0x02, // Server sub-TLV
0x0d, 0x03, 0x50, 0x02, 0x02, // Server sub-TLV
};
const uint8_t kSeqNumbers13[] = {1, 129, 129};
const uint8_t kPreferredSeqNum13 = 129;
const uint8_t kPreferredVer13 = 2;
const uint8_t kNetworkData14[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x13, 0x81, 0x02, 0x5c, 0x07, // Service TLV
0x0d, 0x03, 0x50, 0x00, 0x01, // Server sub-TLV
0x0d, 0x03, 0x50, 0x01, 0x02, // Server sub-TLV
0x0d, 0x03, 0x50, 0x02, 0x03, // Server sub-TLV
};
const uint8_t kSeqNumbers14[] = {7, 7, 7};
const uint8_t kPreferredSeqNum14 = 7;
const uint8_t kPreferredVer14 = 1;
const uint8_t kNetworkData15[] = {
0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
0x0b, 0x17, 0x81, 0x02, 0x5c, 0x03, // Service TLV
0x0d, 0x03, 0x50, 0x00, 0x01, // Server sub-TLV
0x0d, 0x03, 0x50, 0x01, 0x02, // Server sub-TLV
0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
0x0d, 0x03, 0x50, 0x03, 0x01, // Server sub-TLV
};
const uint8_t kSeqNumbers15[] = {3, 3, 3, 3};
const uint8_t kPreferredSeqNum15 = 3;
const uint8_t kPreferredVer15 = 0;
#define TEST_CASE(Num) \
{ \
kNetworkData##Num, sizeof(kNetworkData##Num), kSeqNumbers##Num, sizeof(kSeqNumbers##Num), \
kPreferredSeqNum##Num, kPreferredVer##Num \
}
const TestInfo kTests[] = {
{kNetworkData1, sizeof(kNetworkData1), kSeqNumbers1, sizeof(kSeqNumbers1), kPreferredSeqNum1},
{kNetworkData2, sizeof(kNetworkData2), kSeqNumbers2, sizeof(kSeqNumbers2), kPreferredSeqNum2},
{kNetworkData3, sizeof(kNetworkData3), kSeqNumbers3, sizeof(kSeqNumbers3), kPreferredSeqNum3},
{kNetworkData4, sizeof(kNetworkData4), kSeqNumbers4, sizeof(kSeqNumbers4), kPreferredSeqNum4},
{kNetworkData5, sizeof(kNetworkData5), kSeqNumbers5, sizeof(kSeqNumbers5), kPreferredSeqNum5},
{kNetworkData6, sizeof(kNetworkData6), kSeqNumbers6, sizeof(kSeqNumbers6), kPreferredSeqNum6},
{kNetworkData7, sizeof(kNetworkData7), kSeqNumbers7, sizeof(kSeqNumbers7), kPreferredSeqNum7},
{kNetworkData8, sizeof(kNetworkData8), kSeqNumbers8, sizeof(kSeqNumbers8), kPreferredSeqNum8},
{kNetworkData9, sizeof(kNetworkData9), kSeqNumbers9, sizeof(kSeqNumbers9), kPreferredSeqNum9},
{kNetworkData10, sizeof(kNetworkData10), kSeqNumbers10, sizeof(kSeqNumbers10), kPreferredSeqNum10},
{kNetworkData11, sizeof(kNetworkData11), kSeqNumbers11, sizeof(kSeqNumbers11), kPreferredSeqNum11},
TEST_CASE(1), TEST_CASE(2), TEST_CASE(3), TEST_CASE(4), TEST_CASE(5),
TEST_CASE(6), TEST_CASE(7), TEST_CASE(8), TEST_CASE(9), TEST_CASE(10),
TEST_CASE(11), TEST_CASE(12), TEST_CASE(13), TEST_CASE(14), TEST_CASE(15),
};
Service::Manager &manager = instance->Get<Service::Manager>();
@@ -959,8 +1028,9 @@ void TestNetworkDataDsnSrpAnycastSeqNumSelection(void)
{
SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
printf("\n { %s, seq:%d, rlco16:%04x }", anycastInfo.mAnycastAddress.ToString().AsCString(),
anycastInfo.mSequenceNumber, anycastInfo.mRloc16);
printf("\n { %s, seq:%u, version:%u, rlco16:%04x }", anycastInfo.mAnycastAddress.ToString().AsCString(),
anycastInfo.mSequenceNumber, anycastInfo.mVersion, anycastInfo.mRloc16);
VerifyOrQuit(anycastInfo.mSequenceNumber == test.mSeqNumbers[index]);
VerifyOrQuit(anycastInfo.mRloc16 == 0x5000 + index);
@@ -969,8 +1039,9 @@ void TestNetworkDataDsnSrpAnycastSeqNumSelection(void)
VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound);
SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
printf("\n preferred -> seq:%d ", anycastInfo.mSequenceNumber);
printf("\n preferred -> seq:%u, version:%u ", anycastInfo.mSequenceNumber, anycastInfo.mVersion);
VerifyOrQuit(anycastInfo.mSequenceNumber == test.mPreferredSeqNum);
VerifyOrQuit(anycastInfo.mVersion == test.mPreferredVersion);
}
testFreeInstance(instance);