[coap] clear cached coap requests with rloc source when rloc changes (#4485)

This commit helps to reduce unnecessary CoAP retransmission when rloc
changes. When comes to SRV_DATA.ntf, it also helps to avoid invalid
network data registration. Take the issue reported in #4472 as example,
in a Thread Network with packet loss, the child server may switch parents
frequently, there might be cached SRV_DATA.ntf including old rloc16,
both the cached one and new one might be sent after switched, causing
Leader improperly contain two server entries in the Network Data.
This commit is contained in:
Rongli Sun
2020-02-24 13:13:01 -08:00
committed by Jonathan Hui
parent 206da76b26
commit ea29b88f78
3 changed files with 32 additions and 0 deletions
+18
View File
@@ -79,6 +79,24 @@ void CoapBase::ClearRequestsAndResponses(void)
mResponsesQueue.DequeueAllResponses();
}
void CoapBase::ClearRequests(const Ip6::Address &aAddress)
{
Message *nextMessage;
// Remove pending messages with the specified source.
for (Message *message = static_cast<Message *>(mPendingRequests.GetHead()); message != NULL; message = nextMessage)
{
CoapMetadata coapMetadata;
nextMessage = static_cast<Message *>(message->GetNext());
coapMetadata.ReadFrom(*message);
if (coapMetadata.mSourceAddress == aAddress)
{
FinalizeCoapTransaction(*message, coapMetadata, NULL, NULL, OT_ERROR_ABORT);
}
}
}
otError CoapBase::AddResource(Resource &aResource)
{
return mResources.Add(aResource);
+8
View File
@@ -453,6 +453,14 @@ public:
*/
void ClearRequestsAndResponses(void);
/**
* This method clears requests with specified source address used by this CoAP agent.
*
* @param[in] aAddress A reference to the specified address.
*
*/
void ClearRequests(const Ip6::Address &aAddress);
/**
* This method adds a resource to the CoAP server.
*
+6
View File
@@ -978,6 +978,12 @@ void Mle::SetRloc16(uint16_t aRloc16)
if (aRloc16 != oldRloc16)
{
otLogNoteMle("RLOC16 %04x -> %04x", oldRloc16, aRloc16);
// Clear cached CoAP with old RLOC source
if (oldRloc16 != Mac::kShortAddrInvalid)
{
Get<Coap::Coap>().ClearRequests(mMeshLocal16.GetAddress());
}
}
Get<ThreadNetif>().RemoveUnicastAddress(mMeshLocal16);