mirror of
https://github.com/espressif/openthread.git
synced 2026-09-05 16:50:05 +00:00
[mdns] alternate platform API for signaling local address changes (#11394)
This commit introduces an alternate mechanism for the platform layer to signal local host address changes to the OpenThread mDNS module. The existing approach, where the platform invokes `otPlatMdnsHandleHostAddressEvent()` for each added or removed address, remains supported. The new approach allows the platform to call the newly added `otPlatMdnsHandleHostAddressRemoveAll()` callback once, immediately followed by invoking `otPlatMdnsHandleHostAddressEvent` for every currently assigned IPv4 and IPv6 address on the interface. These two approaches offer flexibility for platforms with varying capabilities accommodating different operating systems and network stacks. Some network stacks may provide mechanisms to identify the added or removed addresses, while others may only provide the new list upon a change. The `test_mdns` unit test is updated to validate this newly added mechanism.
This commit is contained in:
@@ -52,7 +52,7 @@ extern "C" {
|
||||
*
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (494)
|
||||
#define OPENTHREAD_API_VERSION (495)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -161,18 +161,25 @@ extern void otPlatMdnsHandleReceive(otInstance *aInstance,
|
||||
/**
|
||||
* Callback to notify OpenThread mDNS module of host address changes.
|
||||
*
|
||||
* When `otPlatMdnsSetListeningEnabled()` enables mDNS listening on an @p aInfraIfIndex, the platform MUST monitor and
|
||||
* When `otPlatMdnsSetListeningEnabled()` enables mDNS listening on an `aInfraIfIndex`, the platform MUST monitor and
|
||||
* report ALL IPv4 and IPv6 addresses assigned to this network interface.
|
||||
*
|
||||
* When mDNS is enabled:
|
||||
* - The platform MUST retrieve ALL currently assigned IPv4 and IPv6 addresses on the specified interface.
|
||||
* - For each retrieved address, the platform MUST call `otPlatMdnsHandleHostAddressEvent()`.
|
||||
* - For each retrieved address, the platform MUST call `otPlatMdnsHandleHostAddressEvent()` to add the address.
|
||||
* - The IPv4 addresses are represented using IPv4-mapped IPv6 format.
|
||||
*
|
||||
* Ongoing monitoring (while enabled):
|
||||
* - The platform MUST continuously monitor the specified interface for address changes.
|
||||
* - If any addresses are added or removed, the platform MUST call this callback for each affected address, indicating
|
||||
* the change (addition or removal using @p aAdded).
|
||||
* - When the address list changes, the platform MUST notify the OpenThread stack of the change using one of the
|
||||
* following methods:
|
||||
* A. Call this callback for each affected address, indicating the change (addition or removal using @p aAdded).
|
||||
* B. Alternatively, call the `otPlatMdnsHandleHostAddressRemoveAll()` callback once, immediately followed by
|
||||
* invoking this callback for every currently assigned IPv4 and IPv6 address on the interface adding them
|
||||
* (@p aAdded set to `TRUE`), providing the completed updated address list.
|
||||
* - These two approaches offer flexibility for platforms with varying capabilities, such as different operating
|
||||
* systems and network stacks. Some network stacks may provide mechanisms to identify the added or removed
|
||||
* addresses, while others may only provide the new list upon a change.
|
||||
*
|
||||
* When mDNS is disabled:
|
||||
* - The platform MUST cease monitoring for address changes on the interface.
|
||||
@@ -199,6 +206,16 @@ extern void otPlatMdnsHandleHostAddressEvent(otInstance *aInstance,
|
||||
bool aAdded,
|
||||
uint32_t aInfraIfIndex);
|
||||
|
||||
/**
|
||||
* Callback to notify OpenThread mDNS module to remove all previously added host IPv4 and IPv6 addresses.
|
||||
*
|
||||
* See documentation of `otPlatMdnsHandleHostAddressEvent()` for how this callback MUST be used.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance.
|
||||
* @param[in] aInfraIfIndex The interface index.
|
||||
*/
|
||||
extern void otPlatMdnsHandleHostAddressRemoveAll(otInstance *aInstance, uint32_t aInfraIfIndex);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -63,6 +63,11 @@ extern "C" void otPlatMdnsHandleHostAddressEvent(otInstance *aInstance,
|
||||
AsCoreType(aInstance).Get<Core>().HandleHostAddressEvent(AsCoreType(aAddress), aAdded, aInfraIfIndex);
|
||||
}
|
||||
|
||||
extern "C" void otPlatMdnsHandleHostAddressRemoveAll(otInstance *aInstance, uint32_t aInfraIfIndex)
|
||||
{
|
||||
AsCoreType(aInstance).Get<Core>().HandleHostAddressRemoveAll(aInfraIfIndex);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Core
|
||||
|
||||
@@ -284,6 +289,8 @@ void Core::HandleHostAddressEvent(const Ip6::Address &aAddress, bool aAdded, uin
|
||||
mLocalHost.HandleAddressEvent(aAddress, aAdded, aInfraIfIndex);
|
||||
}
|
||||
|
||||
void Core::HandleHostAddressRemoveAll(uint32_t aInfraIfIndex) { mLocalHost.HandleAddressRemoveAll(aInfraIfIndex); }
|
||||
|
||||
void Core::HandleMessage(Message &aMessage, bool aIsUnicast, const AddressInfo &aSenderAddress)
|
||||
{
|
||||
OwnedPtr<Message> messagePtr(&aMessage);
|
||||
@@ -1593,6 +1600,30 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Core::LocalHost::HandleAddressRemoveAll(uint32_t aInfraIfIndex)
|
||||
{
|
||||
VerifyOrExit(Get<Core>().mIsEnabled);
|
||||
VerifyOrExit(aInfraIfIndex == Get<Core>().mInfraIfIndex);
|
||||
|
||||
mAddrEvents.Clear();
|
||||
mEventTimer.Stop();
|
||||
|
||||
LogInfo("Host address event: remove all");
|
||||
|
||||
for (const Ip6::Address &address : mIp4Addresses)
|
||||
{
|
||||
HandleAddressEvent(address, /* aAdded */ false, aInfraIfIndex);
|
||||
}
|
||||
|
||||
for (const Ip6::Address &address : mIp6Addresses)
|
||||
{
|
||||
HandleAddressEvent(address, /* aAdded */ false, aInfraIfIndex);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Core::LocalHost::HandleEventTimer(void)
|
||||
{
|
||||
// Process all saved `AddrEvents` and update IPv4 and IPv6
|
||||
|
||||
@@ -82,6 +82,8 @@ extern "C" void otPlatMdnsHandleHostAddressEvent(otInstance *aInstance,
|
||||
bool aAdded,
|
||||
uint32_t aInfraIfIndex);
|
||||
|
||||
extern "C" void otPlatMdnsHandleHostAddressRemoveAll(otInstance *aInstance, uint32_t aInfraIfIndex);
|
||||
|
||||
/**
|
||||
* Implements Multicast DNS (mDNS) core.
|
||||
*/
|
||||
@@ -99,6 +101,8 @@ class Core : public InstanceLocator, private NonCopyable
|
||||
bool aAdded,
|
||||
uint32_t aInfraIfIndex);
|
||||
|
||||
friend void otPlatMdnsHandleHostAddressRemoveAll(otInstance *aInstance, uint32_t aInfraIfIndex);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initializes a `Core` instance.
|
||||
@@ -1144,6 +1148,7 @@ private:
|
||||
const AddressArray &GetIp4Addresses(void) const { return mIp4Addresses; }
|
||||
const AddressArray &GetIp6Addresses(void) const { return mIp6Addresses; }
|
||||
void HandleAddressEvent(const Ip6::Address &aAddress, bool aAdded, uint32_t aInfraIfIndex);
|
||||
void HandleAddressRemoveAll(uint32_t aInfraIfIndex);
|
||||
void HandleEventTimer(void);
|
||||
void ClearAddresses(void);
|
||||
|
||||
@@ -2204,6 +2209,7 @@ private:
|
||||
|
||||
void AfterInstanceInit(void);
|
||||
void HandleHostAddressEvent(const Ip6::Address &aAddress, bool aAdded, uint32_t aInfraIfIndex);
|
||||
void HandleHostAddressRemoveAll(uint32_t aInfraIfIndex);
|
||||
void InvokeConflictCallback(const char *aName, const char *aServiceType);
|
||||
void HandleMessage(Message &aMessage, bool aIsUnicast, const AddressInfo &aSenderAddress);
|
||||
void AddPassiveSrvTxtCache(const char *aServiceInstance, const char *aServiceType);
|
||||
|
||||
+116
-1
@@ -2321,7 +2321,7 @@ void TestLocalHost(void)
|
||||
localHost.mIp6Addrs.Remove(ip6Address);
|
||||
otPlatMdnsHandleHostAddressEvent(sInstance, &ip6Address, /* aAdded */ false, kInfraIfIndex);
|
||||
|
||||
// Add and then remove the same address quickly
|
||||
// Add then remove the same address quickly
|
||||
// It should not be included in the announcements.
|
||||
|
||||
SuccessOrQuit(ip6Address.FromString("fd00:cafe::333"));
|
||||
@@ -2387,6 +2387,121 @@ void TestLocalHost(void)
|
||||
sDnsMessages.Clear();
|
||||
}
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
Log("Signal removal of all host addresses and add them all back");
|
||||
|
||||
otPlatMdnsHandleHostAddressRemoveAll(sInstance, kInfraIfIndex);
|
||||
|
||||
for (Ip6::Address &ip6Addr : localHost.mIp6Addrs)
|
||||
{
|
||||
otPlatMdnsHandleHostAddressEvent(sInstance, &ip6Addr, /* aAdded */ true, kInfraIfIndex);
|
||||
}
|
||||
|
||||
for (Ip4::Address &ip4Addr : localHost.mIp4Addrs)
|
||||
{
|
||||
ip6Address.SetToIp4Mapped(ip4Addr);
|
||||
otPlatMdnsHandleHostAddressEvent(sInstance, &ip6Address, /* aAdded */ true, kInfraIfIndex);
|
||||
}
|
||||
|
||||
Log("Validate that there are no announcements");
|
||||
|
||||
sDnsMessages.Clear();
|
||||
|
||||
AdvanceTime(10 * 1000);
|
||||
VerifyOrQuit(sDnsMessages.IsEmpty());
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
Log("Signal removal of all addr, add them all back with one extra IPv6 and one extra IPv4 addr");
|
||||
|
||||
otPlatMdnsHandleHostAddressRemoveAll(sInstance, kInfraIfIndex);
|
||||
|
||||
SuccessOrQuit(ip6Address.FromString("fd00:cafe::5555"));
|
||||
SuccessOrQuit(localHost.mIp6Addrs.PushBack(ip6Address));
|
||||
|
||||
for (Ip6::Address &ip6Addr : localHost.mIp6Addrs)
|
||||
{
|
||||
otPlatMdnsHandleHostAddressEvent(sInstance, &ip6Addr, /* aAdded */ true, kInfraIfIndex);
|
||||
}
|
||||
|
||||
SuccessOrQuit(ip4Address.FromString("200.0.64.13"));
|
||||
SuccessOrQuit(localHost.mIp4Addrs.PushBack(ip4Address));
|
||||
|
||||
for (Ip4::Address &ip4Addr : localHost.mIp4Addrs)
|
||||
{
|
||||
ip6Address.SetToIp4Mapped(ip4Addr);
|
||||
otPlatMdnsHandleHostAddressEvent(sInstance, &ip6Address, /* aAdded */ true, kInfraIfIndex);
|
||||
}
|
||||
|
||||
Log("Validate the announcements");
|
||||
|
||||
sDnsMessages.Clear();
|
||||
|
||||
AdvanceTime(5);
|
||||
|
||||
for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
|
||||
{
|
||||
AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
|
||||
|
||||
VerifyOrQuit(!sDnsMessages.IsEmpty());
|
||||
dnsMsg = sDnsMessages.GetHead();
|
||||
dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 8, /* Auth */ 0, /* Addnl */ 1);
|
||||
dnsMsg->Validate(localHost, kInAnswerSection, kCheckAaaa | kCheckA);
|
||||
VerifyOrQuit(dnsMsg->GetNext() == nullptr);
|
||||
sDnsMessages.Clear();
|
||||
}
|
||||
|
||||
AdvanceTime(10 * 1000);
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
Log("Signal removal of all addresses and add some back");
|
||||
|
||||
otPlatMdnsHandleHostAddressRemoveAll(sInstance, kInfraIfIndex);
|
||||
|
||||
for (Ip6::Address &ip6Addr : localHost.mIp6Addrs)
|
||||
{
|
||||
otPlatMdnsHandleHostAddressEvent(sInstance, &ip6Addr, /* aAdded */ true, kInfraIfIndex);
|
||||
}
|
||||
|
||||
Log("Before previous events are processed, signal removal of all addresses again");
|
||||
Log("And add them all back without the recently added extra IPv6 and IPv4 addresses");
|
||||
|
||||
AdvanceTime(1);
|
||||
|
||||
otPlatMdnsHandleHostAddressRemoveAll(sInstance, kInfraIfIndex);
|
||||
otPlatMdnsHandleHostAddressRemoveAll(sInstance, kInfraIfIndex);
|
||||
|
||||
localHost.mIp6Addrs.PopBack();
|
||||
localHost.mIp4Addrs.PopBack();
|
||||
|
||||
for (Ip6::Address &ip6Addr : localHost.mIp6Addrs)
|
||||
{
|
||||
otPlatMdnsHandleHostAddressEvent(sInstance, &ip6Addr, /* aAdded */ true, kInfraIfIndex);
|
||||
}
|
||||
|
||||
for (Ip4::Address &ip4Addr : localHost.mIp4Addrs)
|
||||
{
|
||||
ip6Address.SetToIp4Mapped(ip4Addr);
|
||||
otPlatMdnsHandleHostAddressEvent(sInstance, &ip6Address, /* aAdded */ true, kInfraIfIndex);
|
||||
}
|
||||
|
||||
Log("Validate the announcements");
|
||||
|
||||
sDnsMessages.Clear();
|
||||
|
||||
AdvanceTime(5);
|
||||
|
||||
for (uint8_t anncCount = 0; anncCount < kNumAnnounces; anncCount++)
|
||||
{
|
||||
AdvanceTime((anncCount == 0) ? 0 : (1U << (anncCount - 1)) * 1000);
|
||||
|
||||
VerifyOrQuit(!sDnsMessages.IsEmpty());
|
||||
dnsMsg = sDnsMessages.GetHead();
|
||||
dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 6, /* Auth */ 0, /* Addnl */ 1);
|
||||
dnsMsg->Validate(localHost, kInAnswerSection, kCheckAaaa | kCheckA);
|
||||
VerifyOrQuit(dnsMsg->GetNext() == nullptr);
|
||||
sDnsMessages.Clear();
|
||||
}
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
Log("Signal all host IPv4 addresses are removed, validate goodbye announcements");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user