mirror of
https://github.com/espressif/openthread.git
synced 2026-08-02 09:07:47 +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 <errno.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
@@ -41,6 +42,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <openthread/platform/time.h>
|
||||
|
||||
#include "ip6_utils.hpp"
|
||||
#include "platform-posix.h"
|
||||
#include "common/code_utils.hpp"
|
||||
@@ -149,6 +152,10 @@ void MdnsSocket::Update(otSysMainloopContext &aContext)
|
||||
aContext.mMaxFd = mFd4;
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC)
|
||||
UpdateTimeout(aContext.mTimeout);
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
@@ -177,6 +184,10 @@ void MdnsSocket::Process(const otSysMainloopContext &aContext)
|
||||
ReceiveMessage(kIp4Msg);
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC)
|
||||
ProcessTimeout();
|
||||
#endif
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
@@ -214,6 +225,8 @@ otError MdnsSocket::Enable(uint32_t aInfraIfIndex)
|
||||
mEnabled = true;
|
||||
mInfraIfIndex = aInfraIfIndex;
|
||||
|
||||
StartAddressMonitoring();
|
||||
|
||||
LogInfo("Enabled");
|
||||
|
||||
exit:
|
||||
@@ -237,6 +250,8 @@ void MdnsSocket::Disable(uint32_t aInfraIfIndex)
|
||||
|
||||
mEnabled = false;
|
||||
|
||||
StopAddressMonitoring();
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -43,6 +43,15 @@
|
||||
namespace ot {
|
||||
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.
|
||||
*/
|
||||
@@ -106,8 +115,9 @@ public:
|
||||
void SendUnicast(otMessage *aMessage, const otPlatMdnsAddressInfo *aAddress);
|
||||
|
||||
private:
|
||||
static constexpr uint16_t kMaxMessageLength = 2000;
|
||||
static constexpr uint16_t kMdnsPort = 5353;
|
||||
static constexpr uint16_t kMaxMessageLength = 2000;
|
||||
static constexpr uint16_t kMdnsPort = 5353;
|
||||
static constexpr uint64_t kAddrMonitorPeriod = OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR_PERIOD;
|
||||
|
||||
enum MsgType : uint8_t
|
||||
{
|
||||
@@ -131,6 +141,14 @@ private:
|
||||
void SendQueuedMessages(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 JoinOrLeaveIp4MulticastGroup(bool aJoin, uint32_t aInfraIfIndex);
|
||||
void CloseIp4Socket(void);
|
||||
@@ -163,6 +181,9 @@ private:
|
||||
otIp6Address mMulticastIp6Address;
|
||||
otIp4Address mMulticastIp4Address;
|
||||
otInstance *mInstance;
|
||||
#if (OPENTHREAD_POSIX_CONFIG_MDNS_ADDR_MONITOR == OT_POSIX_MDNS_ADDR_MONITOR_PERIODIC)
|
||||
uint64_t mNextReportTime;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace Posix
|
||||
|
||||
@@ -454,6 +454,32 @@
|
||||
#define OPENTHREAD_POSIX_CONFIG_RESOLV_CONF_ENABLED_INIT (!OPENTHREAD_POSIX_CONFIG_ANDROID_ENABLE)
|
||||
#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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user