diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 545cd4a73..eae1d96ea 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -52,7 +52,7 @@ extern "C" { * * @note This number versions both OpenThread platform and user APIs. */ -#define OPENTHREAD_API_VERSION (516) +#define OPENTHREAD_API_VERSION (517) /** * @addtogroup api-instance diff --git a/include/openthread/mdns.h b/include/openthread/mdns.h index c2c2d9b21..481bf20fb 100644 --- a/include/openthread/mdns.h +++ b/include/openthread/mdns.h @@ -184,6 +184,39 @@ otError otMdnsSetEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfI */ bool otMdnsIsEnabled(otInstance *aInstance); +/** + * Enables or disables the mDNS auto-enable mode. + * + * Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE`. + * + * When this mode is enabled, the mDNS module uses the same infrastructure network interface as the Border Routing + * manager. The mDNS module is then automatically enabled or disabled based on the operational state of that interface + * (see `otBorderRoutingInit()` and `otPlatInfraIfStateChanged()`). + * + * It is recommended to use the auto-enable mode on Border Routers. The default state of this mode at initialization + * is controlled by the `OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF` configuration. + * + * The auto-enable mode can be disabled by a call to `otMdnsSetAutoEnableMode(false)` or by an explicit call to + * `otMdnsSetEnabled()`. Deactivating the auto-enable mode with `otMdnsSetAutoEnableMode(false)` will not change the + * current operational state of the mDNS module (e.g., if it is currently enabled, it remains enabled). + * + * @param[in] aInstance The OpenThread instance. + * @param[in] aEnable A boolean to enable or disable the auto-enable mode. + */ +void otMdnsSetAutoEnableMode(otInstance *aInstance, bool aEnable); + +/** + * Indicates whether the auto-enable mode is enabled or disabled. + * + * Requires `OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE`. + * + * @param[in] aInstance The OpenThread instance. + * + * @retval TRUE The auto-enable mode is enabled. + * @retval FALSE The auto-enable mode is disabled. + */ +bool otMdnsGetAutoEnableMode(otInstance *aInstance); + /** * Sets whether the mDNS module is allowed to send questions requesting unicast responses referred to as "QU" questions. * diff --git a/src/cli/cli_mdns.cpp b/src/cli/cli_mdns.cpp index 32b7399b2..df56bcd46 100644 --- a/src/cli/cli_mdns.cpp +++ b/src/cli/cli_mdns.cpp @@ -48,8 +48,23 @@ template <> otError Mdns::Process(Arg aArgs[]) otError error; uint32_t infraIfIndex; - SuccessOrExit(error = aArgs[0].ParseAsUint32(infraIfIndex)); - VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS); +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + if (aArgs[0].IsEmpty()) + { + bool isRunning; + + // If no if-index is provided, we use the Border Router's + // infrastructure if-index (if any). + + SuccessOrExit(error = otBorderRoutingGetInfraIfInfo(GetInstancePtr(), &infraIfIndex, &isRunning)); + VerifyOrExit(isRunning, error = OT_ERROR_INVALID_STATE); + } + else +#endif + { + SuccessOrExit(error = aArgs[0].ParseAsUint32(infraIfIndex)); + VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS); + } SuccessOrExit(error = otMdnsSetEnabled(GetInstancePtr(), true, infraIfIndex)); @@ -81,6 +96,13 @@ exit: return error; } +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE +template <> otError Mdns::Process(Arg aArgs[]) +{ + return ProcessEnableDisable(aArgs, otMdnsGetAutoEnableMode, otMdnsSetAutoEnableMode); +} +#endif + template <> otError Mdns::Process(Arg aArgs[]) { return ProcessEnableDisable(aArgs, otMdnsIsQuestionUnicastAllowed, otMdnsSetQuestionUnicastAllowed); @@ -1241,6 +1263,9 @@ otError Mdns::Process(Arg aArgs[]) } static constexpr Command kCommands[] = { +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + CmdEntry("auto"), +#endif CmdEntry("browser"), #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENTRY_ITERATION_API_ENABLE CmdEntry("browsers"), diff --git a/src/core/api/mdns_api.cpp b/src/core/api/mdns_api.cpp index 1df04df0b..6a44b2826 100644 --- a/src/core/api/mdns_api.cpp +++ b/src/core/api/mdns_api.cpp @@ -46,6 +46,18 @@ otError otMdnsSetEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfI bool otMdnsIsEnabled(otInstance *aInstance) { return AsCoreType(aInstance).Get().IsEnabled(); } +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE +void otMdnsSetAutoEnableMode(otInstance *aInstance, bool aEnable) +{ + AsCoreType(aInstance).Get().SetAutoEnableMode(aEnable); +} + +bool otMdnsGetAutoEnableMode(otInstance *aInstance) +{ + return AsCoreType(aInstance).Get().GetAutoEnableMode(); +} +#endif + void otMdnsSetQuestionUnicastAllowed(otInstance *aInstance, bool aAllow) { AsCoreType(aInstance).Get().SetQuestionUnicastAllowed(aAllow); diff --git a/src/core/border_router/infra_if.cpp b/src/core/border_router/infra_if.cpp index 7ad4fb331..c01751c79 100644 --- a/src/core/border_router/infra_if.cpp +++ b/src/core/border_router/infra_if.cpp @@ -164,7 +164,7 @@ Error InfraIf::HandleStateChanged(uint32_t aIfIndex, bool aIsRunning) Get().HandleInfraIfStateChanged(); #endif -#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE && OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF +#if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE Get().HandleInfraIfStateChanged(); #endif diff --git a/src/core/net/mdns.cpp b/src/core/net/mdns.cpp index e5973072b..10b286d9b 100644 --- a/src/core/net/mdns.cpp +++ b/src/core/net/mdns.cpp @@ -80,6 +80,7 @@ const char Core::kServicesDnssdLabels[] = "_services._dns-sd._udp"; Core::Core(Instance &aInstance) : InstanceLocator(aInstance) , mIsEnabled(false) + , mAutoEnable(kDefaultAutoEnable) , mIsQuestionUnicastAllowed(kDefaultQuAllowed) , mMaxMessageSize(kMaxMessageSize) , mInfraIfIndex(0) @@ -109,10 +110,15 @@ void Core::AfterInstanceInit(void) mLocalHost.GenerateName(); } -Error Core::SetEnabled(bool aEnable, uint32_t aInfraIfIndex) +Error Core::SetEnabled(bool aEnable, uint32_t aInfraIfIndex, Requester aRequester) { Error error = kErrorNone; + if (aRequester == kRequesterUser) + { + mAutoEnable = false; + } + VerifyOrExit(aEnable != mIsEnabled, error = kErrorAlready); mIsEnabled = aEnable; @@ -122,11 +128,12 @@ Error Core::SetEnabled(bool aEnable, uint32_t aInfraIfIndex) if (mIsEnabled) { - LogInfo("Enabling on infra-if-index %lu", ToUlong(mInfraIfIndex)); + LogInfo("%snabling on infra-if-index %lu", (aRequester == kRequesterAuto) ? "Auto-e" : "E", + ToUlong(mInfraIfIndex)); } else { - LogInfo("Disabling"); + LogInfo("%sisabling", (aRequester == kRequesterAuto) ? "Auto-d" : "D"); mLocalHost.ClearAddresses(); mHostEntries.Clear(); @@ -151,12 +158,45 @@ exit: return error; } -#if OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + +void Core::SetAutoEnableMode(bool aEnable) +{ + VerifyOrExit(mAutoEnable != aEnable); + + mAutoEnable = aEnable; + + if (mAutoEnable) + { + if (!Get().IsRunning()) + { + IgnoreError(SetEnabled(false, mInfraIfIndex, kRequesterAuto)); + ExitNow(); + } + + if (IsEnabled()) + { + VerifyOrExit(Get().GetIfIndex() != mInfraIfIndex); + IgnoreError(SetEnabled(false, mInfraIfIndex, kRequesterAuto)); + } + + IgnoreError(SetEnabled(true, Get().GetIfIndex(), kRequesterAuto)); + } + +exit: + return; +} + void Core::HandleInfraIfStateChanged(void) { - IgnoreError(SetEnabled(Get().IsRunning(), Get().GetIfIndex())); + VerifyOrExit(mAutoEnable); + IgnoreError(SetEnabled(Get().IsRunning(), Get().GetIfIndex(), + kRequesterAuto)); +exit: + return; } -#endif + +#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE template Error Core::Register(const ItemInfo &aItemInfo, RequestId aRequestId, RegisterCallback aCallback) diff --git a/src/core/net/mdns.hpp b/src/core/net/mdns.hpp index def39fa30..2b574a9f3 100644 --- a/src/core/net/mdns.hpp +++ b/src/core/net/mdns.hpp @@ -69,6 +69,11 @@ struct otMdnsIterator }; namespace ot { + +namespace BorderRouter { +class InfraIf; +} + namespace Dns { namespace Multicast { @@ -90,6 +95,7 @@ extern "C" void otPlatMdnsHandleHostAddressRemoveAll(otInstance *aInstance, uint class Core : public InstanceLocator, private NonCopyable { friend class ot::Instance; + friend class ot::BorderRouter::InfraIf; friend void otPlatMdnsHandleReceive(otInstance *aInstance, otMessage *aMessage, @@ -172,7 +178,10 @@ public: * @retval kErrorAlready mDNS is already enabled on an enable request, or is already disabled on a disable request. * @retval kErrorFailed Failed to enable/disable mDNS. */ - Error SetEnabled(bool aEnable, uint32_t aInfraIfIndex); + Error SetEnabled(bool aEnable, uint32_t aInfraIfIndex) + { + return SetEnabled(aEnable, aInfraIfIndex, kRequesterUser); + } /** * Indicates whether or not mDNS module is enabled. @@ -182,6 +191,35 @@ public: */ bool IsEnabled(void) const { return mIsEnabled; } +#if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + /** + * Enables or disables the mDNS auto-enable mode. + * + * When this mode is enabled, the mDNS module uses the same infrastructure network interface as the Border Routing + * manager. The mDNS module is then automatically enabled or disabled based on the operational state of that + * interface. + * + * It is recommended to use the auto-enable mode on Border Routers. The default state of this mode at + * initialization is controlled by the `OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF` configuration. + * + * The auto-enable mode can be disabled by a call to `SetAutoEnableMode(false)` or by an explicit call to + * `SetEnabled()`. Deactivating the auto-enable mode with `SetAutoEnableMode(false)` will not change the current + * operational state of the mDNS module (e.g., if it is currently enabled, it remains enabled). + * + * @param[in] aEnable A boolean to enable or disable the auto-enable mode. + */ + void SetAutoEnableMode(bool aEnable); + + /** + * Indicates whether the auto-enable mode is enabled or disabled. + * + * @retval TRUE The auto-enable mode is enabled. + * @retval FALSE The auto-enable mode is disabled. + */ + bool GetAutoEnableMode(void) const { return mAutoEnable; } + +#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + /** * Gets the local host name. * @@ -202,13 +240,6 @@ public: */ Error SetLocalHostName(const char *aName) { return mLocalHost.SetName(aName); } -#if OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF - /** - * Notifies `AdvertisingProxy` that `InfraIf` state changed. - */ - void HandleInfraIfStateChanged(void); -#endif - /** * Sets whether mDNS module is allowed to send questions requesting unicast responses referred to as "QU" questions. * @@ -815,7 +846,8 @@ private: static constexpr uint16_t kUdpPort = 5353; - static constexpr bool kDefaultQuAllowed = OPENTHREAD_CONFIG_MULTICAST_DNS_DEFAULT_QUESTION_UNICAST_ALLOWED; + static constexpr bool kDefaultAutoEnable = OPENTHREAD_CONFIG_MULTICAST_DNS_AUTO_ENABLE_ON_INFRA_IF; + static constexpr bool kDefaultQuAllowed = OPENTHREAD_CONFIG_MULTICAST_DNS_DEFAULT_QUESTION_UNICAST_ALLOWED; static constexpr uint32_t kMaxMessageSize = 1200; @@ -855,6 +887,12 @@ private: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + enum Requester : uint8_t // Used by `SetEnabled()`. + { + kRequesterUser, + kRequesterAuto, + }; + enum Section : uint8_t { kQuestionSection, @@ -2229,6 +2267,8 @@ private: Error Stop(const BrowserResolverType &aBrowserOrResolver); void AfterInstanceInit(void); + Error SetEnabled(bool aEnable, uint32_t aInfraIfIndex, Requester aRequester); + void HandleInfraIfStateChanged(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); @@ -2266,6 +2306,7 @@ private: static const char kServicesDnssdLabels[]; // "_services._dns-sd._udp" bool mIsEnabled; + bool mAutoEnable; bool mIsQuestionUnicastAllowed; uint16_t mMaxMessageSize; uint32_t mInfraIfIndex;