mirror of
https://github.com/espressif/openthread.git
synced 2026-09-15 21:50:08 +00:00
[posix] implement address monitoring in MdnsSocket (#11641)
This commit introduces an initial implementation in `Posix::MdnsSocket` to monitor and report all IPv4 and IPv6 addresses assigned to the infrastructure network interface. This mechanism is used by OpenThread's native mDNS module and was added in PRs #11353 and #11394. A new configuration, `OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR`, is added to select the monitoring strategy. This commit implements the `OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC` approach, where `getifaddrs()` is used to enumerate addresses periodically. The polling interval is configured by `OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR_PERIOD`. Note that the OpenThread mDNS module itself tracks the list of reported addresses and will only take action when there is a change from what was previously announced. This allows the platform to simply report the full list of current addresses at each interval.
This commit is contained in:
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -41,6 +42,8 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <openthread/platform/time.h>
|
||||||
|
|
||||||
#include "ip6_utils.hpp"
|
#include "ip6_utils.hpp"
|
||||||
#include "platform-posix.h"
|
#include "platform-posix.h"
|
||||||
#include "common/code_utils.hpp"
|
#include "common/code_utils.hpp"
|
||||||
@@ -149,6 +152,10 @@ void MdnsSocket::Update(otSysMainloopContext &aContext)
|
|||||||
aContext.mMaxFd = mFd4;
|
aContext.mMaxFd = mFd4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC)
|
||||||
|
UpdateTimeout(aContext.mTimeout);
|
||||||
|
#endif
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -177,6 +184,10 @@ void MdnsSocket::Process(const otSysMainloopContext &aContext)
|
|||||||
ReceiveMessage(kIp4Msg);
|
ReceiveMessage(kIp4Msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC)
|
||||||
|
ProcessTimeout();
|
||||||
|
#endif
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -214,6 +225,8 @@ otError MdnsSocket::Enable(uint32_t aInfraIfIndex)
|
|||||||
mEnabled = true;
|
mEnabled = true;
|
||||||
mInfraIfIndex = aInfraIfIndex;
|
mInfraIfIndex = aInfraIfIndex;
|
||||||
|
|
||||||
|
StartAddressMonitoring();
|
||||||
|
|
||||||
LogInfo("Enabled");
|
LogInfo("Enabled");
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
@@ -237,6 +250,8 @@ void MdnsSocket::Disable(uint32_t aInfraIfIndex)
|
|||||||
|
|
||||||
mEnabled = false;
|
mEnabled = false;
|
||||||
|
|
||||||
|
StopAddressMonitoring();
|
||||||
|
|
||||||
LogInfo("Disabled");
|
LogInfo("Disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,6 +505,89 @@ exit:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
|
// Monitoring address on infra netif
|
||||||
|
|
||||||
|
#if (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC)
|
||||||
|
|
||||||
|
void MdnsSocket::ReportInfraIfAddresses(void)
|
||||||
|
{
|
||||||
|
struct ifaddrs *ifAddrs = nullptr;
|
||||||
|
|
||||||
|
mNextReportTime = otPlatTimeGet() + kAddrMonitorPeriod * OT_US_PER_MS;
|
||||||
|
|
||||||
|
if (getifaddrs(&ifAddrs) < 0)
|
||||||
|
{
|
||||||
|
LogWarn("Failed to get netif addresses: %s", strerror(errno));
|
||||||
|
ExitNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
otPlatMdnsHandleHostAddressRemoveAll(mInstance, mInfraIfIndex);
|
||||||
|
|
||||||
|
for (struct ifaddrs *addr = ifAddrs; addr != nullptr; addr = addr->ifa_next)
|
||||||
|
{
|
||||||
|
otIp6Address ip6Addr;
|
||||||
|
otIp4Address ip4Addr;
|
||||||
|
|
||||||
|
if ((addr->ifa_addr == nullptr) || (if_nametoindex(addr->ifa_name) != mInfraIfIndex))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr->ifa_addr->sa_family == AF_INET6)
|
||||||
|
{
|
||||||
|
ReadIp6AddressFrom(&reinterpret_cast<sockaddr_in6 *>(addr->ifa_addr)->sin6_addr, ip6Addr);
|
||||||
|
}
|
||||||
|
else if (addr->ifa_addr->sa_family == AF_INET)
|
||||||
|
{
|
||||||
|
memcpy(&ip4Addr, &reinterpret_cast<sockaddr_in *>(addr->ifa_addr)->sin_addr.s_addr, sizeof(otIp4Address));
|
||||||
|
otIp4ToIp4MappedIp6Address(&ip4Addr, &ip6Addr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
otPlatMdnsHandleHostAddressEvent(mInstance, &ip6Addr, /* aAdded */ true, mInfraIfIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (ifAddrs != nullptr)
|
||||||
|
{
|
||||||
|
freeifaddrs(ifAddrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MdnsSocket::UpdateTimeout(struct timeval &aTimeout)
|
||||||
|
{
|
||||||
|
uint64_t now = otPlatTimeGet();
|
||||||
|
uint64_t remaining = 1;
|
||||||
|
uint64_t timeout;
|
||||||
|
|
||||||
|
if (mNextReportTime > now)
|
||||||
|
{
|
||||||
|
remaining = mNextReportTime - now;
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout = static_cast<uint64_t>(aTimeout.tv_sec) * OT_US_PER_S + static_cast<uint64_t>(aTimeout.tv_usec);
|
||||||
|
|
||||||
|
if (remaining < timeout)
|
||||||
|
{
|
||||||
|
aTimeout.tv_sec = static_cast<time_t>(remaining / OT_US_PER_S);
|
||||||
|
aTimeout.tv_usec = static_cast<suseconds_t>(remaining % OT_US_PER_S);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MdnsSocket::ProcessTimeout(void)
|
||||||
|
{
|
||||||
|
if (mNextReportTime <= otPlatTimeGet())
|
||||||
|
{
|
||||||
|
ReportInfraIfAddresses();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC)
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
// Socket helpers
|
// Socket helpers
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,15 @@
|
|||||||
namespace ot {
|
namespace ot {
|
||||||
namespace Posix {
|
namespace Posix {
|
||||||
|
|
||||||
|
#define OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC 1
|
||||||
|
#define OT_POSIX_MDNS_ADDR_MONITOR_NETLINK 2
|
||||||
|
|
||||||
|
#if (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_NETLINK)
|
||||||
|
#error "The `OT_POSIX_MDNS_ADDR_MONITOR_NETLINK` is not supported yet"
|
||||||
|
#elif (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR != OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC)
|
||||||
|
#error "The `OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR` is not valid. MUST be one of `OT_POSIX_MDNS_ADDR_MONITOR_*`"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements platform mDNS socket APIs.
|
* Implements platform mDNS socket APIs.
|
||||||
*/
|
*/
|
||||||
@@ -106,8 +115,9 @@ public:
|
|||||||
void SendUnicast(otMessage *aMessage, const otPlatMdnsAddressInfo *aAddress);
|
void SendUnicast(otMessage *aMessage, const otPlatMdnsAddressInfo *aAddress);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint16_t kMaxMessageLength = 2000;
|
static constexpr uint16_t kMaxMessageLength = 2000;
|
||||||
static constexpr uint16_t kMdnsPort = 5353;
|
static constexpr uint16_t kMdnsPort = 5353;
|
||||||
|
static constexpr uint64_t kAddrMonitorPeriod = OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR_PERIOD;
|
||||||
|
|
||||||
enum MsgType : uint8_t
|
enum MsgType : uint8_t
|
||||||
{
|
{
|
||||||
@@ -131,6 +141,14 @@ private:
|
|||||||
void SendQueuedMessages(MsgType aMsgType);
|
void SendQueuedMessages(MsgType aMsgType);
|
||||||
void ReceiveMessage(MsgType aMsgType);
|
void ReceiveMessage(MsgType aMsgType);
|
||||||
|
|
||||||
|
#if (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC)
|
||||||
|
void StartAddressMonitoring(void) { ReportInfraIfAddresses(); }
|
||||||
|
void StopAddressMonitoring(void) {}
|
||||||
|
void ReportInfraIfAddresses(void);
|
||||||
|
void UpdateTimeout(struct timeval &aTimeout);
|
||||||
|
void ProcessTimeout(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
otError OpenIp4Socket(uint32_t aInfraIfIndex);
|
otError OpenIp4Socket(uint32_t aInfraIfIndex);
|
||||||
otError JoinOrLeaveIp4MulticastGroup(bool aJoin, uint32_t aInfraIfIndex);
|
otError JoinOrLeaveIp4MulticastGroup(bool aJoin, uint32_t aInfraIfIndex);
|
||||||
void CloseIp4Socket(void);
|
void CloseIp4Socket(void);
|
||||||
@@ -163,6 +181,9 @@ private:
|
|||||||
otIp6Address mMulticastIp6Address;
|
otIp6Address mMulticastIp6Address;
|
||||||
otIp4Address mMulticastIp4Address;
|
otIp4Address mMulticastIp4Address;
|
||||||
otInstance *mInstance;
|
otInstance *mInstance;
|
||||||
|
#if (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC)
|
||||||
|
uint64_t mNextReportTime;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Posix
|
} // namespace Posix
|
||||||
|
|||||||
@@ -454,6 +454,32 @@
|
|||||||
#define OPENTHREAD_POSIX_CONFIG_RESOLV_CONF_ENABLED_INIT (!OPENTHREAD_POSIX_CONFIG_ANDROID_ENABLE)
|
#define OPENTHREAD_POSIX_CONFIG_RESOLV_CONF_ENABLED_INIT (!OPENTHREAD_POSIX_CONFIG_ANDROID_ENABLE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR
|
||||||
|
*
|
||||||
|
* Specifies the behavior of `MdnsSocket` and how it implements monitoring and reporting of infra-interface IPv4 and
|
||||||
|
* IPv6 addresses.
|
||||||
|
*
|
||||||
|
* The valid values for this config, `OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR_*`, are defined in
|
||||||
|
* `posix/platform/mdns_socket.h`.
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR
|
||||||
|
#define OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR_PERIOD
|
||||||
|
*
|
||||||
|
* Specifies the duration in milliseconds (ms) for the periodic check used by the `MdnsSocket` implementation to
|
||||||
|
* monitor and report the infra-interface IPv4 and IPv6 addresses.
|
||||||
|
*
|
||||||
|
* This is applicable only when `OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR` is set to
|
||||||
|
* `OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR_PERIODIC`.
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR_PERIOD
|
||||||
|
#define OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR_PERIOD (5000)
|
||||||
|
#endif
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------------------
|
||||||
// Removed or renamed POSIX specific configs.
|
// Removed or renamed POSIX specific configs.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user