[srp-client] track registered addresses (#9652)

This commit enhances the SRP client to track registered addresses when
auto host address mode is enabled. A new field `mSrpRegistered` is
added to `Ip6::Netif::UnicastAddress` to track whether the address is
registered by the SRP client.

This optimization ensures that the SRP client only performs
registration when there is a change to the list of addresses that
need to be registered, preventing unnecessary re-registration and
reduces communication overhead, e.g., when a deprecating
non-preferred address which is not registered by SRP client is timed
out and removed.
This commit is contained in:
Abtin Keshavarzian
2023-12-01 10:14:44 -08:00
committed by GitHub
parent 2b57941b85
commit b78b71b537
8 changed files with 145 additions and 34 deletions
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (379)
#define OPENTHREAD_API_VERSION (380)
/**
* @addtogroup api-instance
+1
View File
@@ -189,6 +189,7 @@ typedef struct otNetifAddress
unsigned int mScopeOverride : 4; ///< The IPv6 scope of this address.
bool mRloc : 1; ///< TRUE if the address is an RLOC, FALSE otherwise.
bool mMeshLocal : 1; ///< TRUE if the address is mesh-local, FALSE otherwise.
bool mSrpRegistered : 1; ///< Used by OT core only (indicates whether registered by SRP Client).
const struct otNetifAddress *mNext; ///< A pointer to the next network interface address.
} otNetifAddress;
+20 -4
View File
@@ -377,15 +377,29 @@ exit:
return;
}
void Netif::RemoveUnicastAddress(const UnicastAddress &aAddress)
void Netif::RemoveUnicastAddress(UnicastAddress &aAddress)
{
SuccessOrExit(mUnicastAddresses.Remove(aAddress));
aAddress.mSrpRegistered = false;
SignalUnicastAddressChange(kAddressRemoved, aAddress);
exit:
return;
}
void Netif::UpdatePreferredFlagOn(UnicastAddress &aAddress, bool aPreferred)
{
VerifyOrExit(HasUnicastAddress(aAddress));
VerifyOrExit(aAddress.mPreferred != aPreferred);
SignalUnicastAddressChange(kAddressRemoved, aAddress);
aAddress.mPreferred = aPreferred;
SignalUnicastAddressChange(kAddressAdded, aAddress);
exit:
return;
}
void Netif::SignalUnicastAddressChange(AddressEvent aEvent, const UnicastAddress &aAddress)
{
Event event;
@@ -443,9 +457,10 @@ Error Netif::AddExternalUnicastAddress(const UnicastAddress &aAddress)
entry = mExtUnicastAddressPool.Allocate();
VerifyOrExit(entry != nullptr, error = kErrorNoBufs);
*entry = aAddress;
entry->mRloc = false;
entry->mMeshLocal = false;
*entry = aAddress;
entry->mRloc = false;
entry->mMeshLocal = false;
entry->mSrpRegistered = false;
mUnicastAddresses.Push(*entry);
SignalUnicastAddressChange(kAddressAdded, *entry);
@@ -504,6 +519,7 @@ void Netif::ApplyNewMeshLocalPrefix(void)
if (address.mMeshLocal)
{
SignalUnicastAddressChange(kAddressRemoved, address);
address.mSrpRegistered = false;
address.GetAddress().SetPrefix(Get<Mle::Mle>().GetMeshLocalPrefix());
SignalUnicastAddressChange(kAddressAdded, address);
}
+21 -1
View File
@@ -397,6 +397,14 @@ public:
*/
const LinkedList<UnicastAddress> &GetUnicastAddresses(void) const { return mUnicastAddresses; }
/**
* Returns the linked list of unicast addresses.
*
* @returns The linked list of unicast addresses.
*
*/
LinkedList<UnicastAddress> &GetUnicastAddresses(void) { return mUnicastAddresses; }
/**
* Adds a unicast address to the network interface.
*
@@ -421,7 +429,19 @@ public:
* @param[in] aAddress A reference to the unicast address.
*
*/
void RemoveUnicastAddress(const UnicastAddress &aAddress);
void RemoveUnicastAddress(UnicastAddress &aAddress);
/**
* Updates the preferred flag on a previously added (internal to OpenThread core) unicast address.
*
* If the address is not added to the network interface or the current preferred flag of @p aAddress is the same as
* the given @p aPreferred, no action is performed.
*
* @param[in] aAddress The unicast address
* @param[in] aPreferred The new value for preferred flag.
*
*/
void UpdatePreferredFlagOn(UnicastAddress &aAddress, bool aPreferred);
/**
* Indicates whether or not an address is assigned to the interface.
+90 -26
View File
@@ -244,13 +244,13 @@ Client::Client(Instance &aInstance)
, mState(kStateStopped)
, mTxFailureRetryCount(0)
, mShouldRemoveKeyLease(false)
, mAutoHostAddressAddedMeshLocal(false)
, mSingleServiceMode(false)
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
, mServiceKeyRecordEnabled(false)
, mUseShortLeaseOption(false)
#endif
, mUpdateMessageId(0)
, mAutoHostAddressCount(0)
, mRetryWaitInterval(kMinRetryWaitInterval)
, mTtl(0)
, mLease(0)
@@ -421,20 +421,11 @@ void Client::HandleNotifierEvents(Events aEvents)
}
#endif
if (mHostInfo.IsAutoAddressEnabled())
if (aEvents.ContainsAny(kEventIp6AddressAdded | kEventIp6AddressRemoved | kEventThreadMeshLocalAddrChanged) &&
ShouldUpdateHostAutoAddresses())
{
Events::Flags eventFlags = (kEventIp6AddressAdded | kEventIp6AddressRemoved);
if (mAutoHostAddressAddedMeshLocal)
{
eventFlags |= kEventThreadMeshLocalAddrChanged;
}
if (aEvents.ContainsAny(eventFlags))
{
IgnoreError(UpdateHostInfoStateOnAddressChange());
UpdateState();
}
IgnoreError(UpdateHostInfoStateOnAddressChange());
UpdateState();
}
}
@@ -494,6 +485,13 @@ Error Client::EnableAutoHostAddress(void)
VerifyOrExit(!mHostInfo.IsAutoAddressEnabled());
SuccessOrExit(error = UpdateHostInfoStateOnAddressChange());
for (Ip6::Netif::UnicastAddress &unicastAddress : Get<ThreadNetif>().GetUnicastAddresses())
{
unicastAddress.mSrpRegistered = false;
}
mAutoHostAddressCount = 0;
mHostInfo.EnableAutoAddress();
UpdateState();
@@ -515,6 +513,68 @@ exit:
return error;
}
bool Client::ShouldUpdateHostAutoAddresses(void) const
{
bool shouldUpdate = false;
uint16_t registeredCount = 0;
Ip6::Netif::UnicastAddress &ml64 = Get<Mle::Mle>().GetMeshLocal64UnicastAddress();
VerifyOrExit(mHostInfo.IsAutoAddressEnabled());
// Check all addresses on `ThreadNetif` excluding the mesh local
// EID (`ml64`). If any address should be registered but is not,
// or if any address was registered earlier but no longer should
// be, the host information needs to be re-registered to update
// the addresses. If there is no eligible address, then `ml64`
// should be registered, so its status is checked. Finally, the
// number of addresses that should be registered is verified
// against the previous value `mAutoHostAddressCount` to handle
// the case where an earlier registered address is now removed.
for (const Ip6::Netif::UnicastAddress &unicastAddress : Get<ThreadNetif>().GetUnicastAddresses())
{
if (&unicastAddress == &ml64)
{
continue;
}
if (ShouldHostAutoAddressRegister(unicastAddress) != unicastAddress.mSrpRegistered)
{
ExitNow(shouldUpdate = true);
}
if (unicastAddress.mSrpRegistered)
{
registeredCount++;
}
}
if (registeredCount == 0)
{
ExitNow(shouldUpdate = !ml64.mSrpRegistered);
}
shouldUpdate = (registeredCount != mAutoHostAddressCount);
exit:
return shouldUpdate;
}
bool Client::ShouldHostAutoAddressRegister(const Ip6::Netif::UnicastAddress &aUnicastAddress) const
{
bool shouldRegister = false;
VerifyOrExit(aUnicastAddress.mValid);
VerifyOrExit(aUnicastAddress.mPreferred);
VerifyOrExit(!aUnicastAddress.GetAddress().IsLinkLocal());
VerifyOrExit(!Get<Mle::Mle>().IsMeshLocalAddress(aUnicastAddress.GetAddress()));
shouldRegister = true;
exit:
return shouldRegister;
}
Error Client::UpdateHostInfoStateOnAddressChange(void)
{
Error error = kErrorNone;
@@ -1244,25 +1304,29 @@ Error Client::AppendHostDescriptionInstruction(Message &aMessage, Info &aInfo)
// and mesh-local addresses. If no address is appended, we include
// the mesh local EID.
mAutoHostAddressAddedMeshLocal = true;
mAutoHostAddressCount = 0;
for (const Ip6::Netif::UnicastAddress &unicastAddress : Get<ThreadNetif>().GetUnicastAddresses())
for (Ip6::Netif::UnicastAddress &unicastAddress : Get<ThreadNetif>().GetUnicastAddresses())
{
const Ip6::Address &address = unicastAddress.GetAddress();
if (address.IsLinkLocal() || Get<Mle::Mle>().IsMeshLocalAddress(address) || !unicastAddress.mPreferred ||
!unicastAddress.mValid)
if (ShouldHostAutoAddressRegister(unicastAddress))
{
continue;
SuccessOrExit(error = AppendAaaaRecord(unicastAddress.GetAddress(), aMessage, aInfo));
unicastAddress.mSrpRegistered = true;
mAutoHostAddressCount++;
}
else
{
unicastAddress.mSrpRegistered = false;
}
SuccessOrExit(error = AppendAaaaRecord(address, aMessage, aInfo));
mAutoHostAddressAddedMeshLocal = false;
}
if (mAutoHostAddressAddedMeshLocal)
if (mAutoHostAddressCount == 0)
{
SuccessOrExit(error = AppendAaaaRecord(Get<Mle::Mle>().GetMeshLocal64(), aMessage, aInfo));
Ip6::Netif::UnicastAddress &ml64 = Get<Mle::Mle>().GetMeshLocal64UnicastAddress();
SuccessOrExit(error = AppendAaaaRecord(ml64.GetAddress(), aMessage, aInfo));
ml64.mSrpRegistered = true;
mAutoHostAddressCount++;
}
}
else
+3 -1
View File
@@ -1001,6 +1001,8 @@ private:
void Pause(void);
void HandleNotifierEvents(Events aEvents);
void HandleRoleChanged(void);
bool ShouldUpdateHostAutoAddresses(void) const;
bool ShouldHostAutoAddressRegister(const Ip6::Netif::UnicastAddress &aUnicastAddress) const;
Error UpdateHostInfoStateOnAddressChange(void);
void UpdateServiceStateToRemove(Service &aService);
State GetState(void) const { return mState; }
@@ -1065,7 +1067,6 @@ private:
State mState;
uint8_t mTxFailureRetryCount : 4;
bool mShouldRemoveKeyLease : 1;
bool mAutoHostAddressAddedMeshLocal : 1;
bool mSingleServiceMode : 1;
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
bool mServiceKeyRecordEnabled : 1;
@@ -1073,6 +1074,7 @@ private:
#endif
uint16_t mUpdateMessageId;
uint16_t mAutoHostAddressCount;
uint32_t mRetryWaitInterval;
TimeMilli mLeaseRenewTime;
+1 -1
View File
@@ -785,7 +785,7 @@ void AddressResolver::HandleTmf<kUriAddressError>(Coap::Message &aMessage, const
SuccessOrExit(error = Tlv::Find<ThreadTargetTlv>(aMessage, target));
SuccessOrExit(error = Tlv::Find<ThreadMeshLocalEidTlv>(aMessage, meshLocalIid));
for (const Ip6::Netif::UnicastAddress &address : Get<ThreadNetif>().GetUnicastAddresses())
for (Ip6::Netif::UnicastAddress &address : Get<ThreadNetif>().GetUnicastAddresses())
{
if (address.GetAddress() == target && Get<Mle::MleRouter>().GetMeshLocal64().GetIid() != meshLocalIid)
{
+8
View File
@@ -530,6 +530,14 @@ public:
*/
const Ip6::Address &GetMeshLocal64(void) const { return mMeshLocal64.GetAddress(); }
/**
* Returns a reference to the ML-EID as a `Netif::UnicastAddress`.
*
* @returns A reference to the ML-EID.
*
*/
Ip6::Netif::UnicastAddress &GetMeshLocal64UnicastAddress(void) { return mMeshLocal64; }
/**
* Returns the Router ID of the Leader.
*