Skip to content

Commit 488cbb1

Browse files
committed
[dnssd] deduplicate service instance updates
When OTBR_MDNS=mDNSResponder is enabled, redundant service browse and resolve callbacks can occur for already discovered TREL peers. Because TrelDnssd::OnTrelServiceInstanceAdded unconditionally called OnTrelServiceInstanceRemoved right at the start of the function, each duplicate mDNS update triggered peer removal (kDnssdRemoved) followed by peer re-addition (kReAdded). This continuous state cycling in OpenThread's TrelPeerTable caused unnecessary multi-radio link probing and out-of-order fragment delivery between 15.4 and TREL interfaces, leading to kErrorDuplicated drops on valid ICMPv6 Echo Reply fragments during integration tests. Before calling OnTrelServiceInstanceRemoved, check if the peer entry already exists with identical socket address and TXT data. If unchanged, update mDiscoverTime and exit without triggering peer removal or re-addition in OpenThread.
1 parent 9aa79a0 commit 488cbb1

2 files changed

Lines changed: 32 additions & 3 deletions

File tree

src/trel_dnssd/trel_dnssd.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,7 @@ void TrelDnssd::OnTrelServiceInstanceAdded(const Mdns::Publisher::DiscoveredInst
289289
Ip6Address selectedAddress;
290290
otPlatTrelPeerInfo peerInfo;
291291

292-
// Remove any existing TREL service instance before adding
293-
OnTrelServiceInstanceRemoved(instanceName);
292+
memset(&peerInfo, 0, sizeof(peerInfo));
294293

295294
otbrLogDebug("Peer discovered: %s hostname %s addresses %zu port %d priority %d "
296295
"weight %d",
@@ -331,6 +330,25 @@ void TrelDnssd::OnTrelServiceInstanceAdded(const Mdns::Publisher::DiscoveredInst
331330

332331
VerifyOrExit(peer.mValid, otbrLogWarning("Peer %s is invalid", aInstanceInfo.mName.c_str()));
333332

333+
auto it = mPeers.find(instanceName);
334+
if (it != mPeers.end())
335+
{
336+
if (it->second.Matches(peer))
337+
{
338+
it->second.mDiscoverTime = Clock::now();
339+
ExitNow();
340+
}
341+
342+
if (memcmp(&it->second.mExtAddr, &peer.mExtAddr, sizeof(otExtAddress)) != 0)
343+
{
344+
OnTrelServiceInstanceRemoved(instanceName);
345+
}
346+
else
347+
{
348+
mPeers.erase(it);
349+
}
350+
}
351+
334352
otPlatTrelHandleDiscoveredPeerInfo(mHost.GetInstance(), &peerInfo);
335353

336354
mPeers.emplace(instanceName, peer);
@@ -387,6 +405,8 @@ void TrelDnssd::NotifyRemovePeer(const Peer &aPeer)
387405
{
388406
otPlatTrelPeerInfo peerInfo;
389407

408+
memset(&peerInfo, 0, sizeof(peerInfo));
409+
390410
peerInfo.mRemoved = true;
391411
peerInfo.mTxtData = aPeer.mTxtData.data();
392412
peerInfo.mTxtLength = aPeer.mTxtData.size();
@@ -466,7 +486,8 @@ uint16_t TrelDnssd::CountDuplicatePeers(const TrelDnssd::Peer &aPeer)
466486
continue;
467487
}
468488

469-
if (!memcmp(&entry.second.mSockAddr, &aPeer.mSockAddr, sizeof(otSockAddr)) &&
489+
if ((entry.second.mSockAddr.mPort == aPeer.mSockAddr.mPort) &&
490+
!memcmp(&entry.second.mSockAddr.mAddress, &aPeer.mSockAddr.mAddress, sizeof(otIp6Address)) &&
470491
!memcmp(&entry.second.mExtAddr, &aPeer.mExtAddr, sizeof(otExtAddress)))
471492
{
472493
count++;

src/trel_dnssd/trel_dnssd.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#if OTBR_ENABLE_TREL_DNSSD
4040

4141
#include <assert.h>
42+
#include <string.h>
4243
#include <utility>
4344

4445
#include <openthread/instance.h>
@@ -141,6 +142,13 @@ class TrelDnssd : public Mdns::StateObserver
141142

142143
void ReadExtAddrFromTxtData(void);
143144

145+
bool Matches(const Peer &aOther) const
146+
{
147+
return (mSockAddr.mPort == aOther.mSockAddr.mPort) &&
148+
(memcmp(&mSockAddr.mAddress, &aOther.mSockAddr.mAddress, sizeof(otIp6Address)) == 0) &&
149+
(mTxtData == aOther.mTxtData);
150+
}
151+
144152
Clock::time_point mDiscoverTime;
145153
std::vector<uint8_t> mTxtData;
146154
otSockAddr mSockAddr;

0 commit comments

Comments
 (0)