diff options
Diffstat (limited to 'src/trel_dnssd')
-rw-r--r-- | src/trel_dnssd/CMakeLists.txt | 37 | ||||
-rw-r--r-- | src/trel_dnssd/trel_dnssd.cpp | 522 | ||||
-rw-r--r-- | src/trel_dnssd/trel_dnssd.hpp | 196 |
3 files changed, 755 insertions, 0 deletions
diff --git a/src/trel_dnssd/CMakeLists.txt b/src/trel_dnssd/CMakeLists.txt new file mode 100644 index 00000000..b0c4a93b --- /dev/null +++ b/src/trel_dnssd/CMakeLists.txt @@ -0,0 +1,37 @@ +# +# Copyright (c) 2021, The OpenThread Authors. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the copyright holder nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +add_library(otbr-trel-dnssd + trel_dnssd.cpp + trel_dnssd.hpp +) + +target_link_libraries(otbr-trel-dnssd PRIVATE + $<$<BOOL:${OTBR_MDNS}>:otbr-mdns> + otbr-common +) diff --git a/src/trel_dnssd/trel_dnssd.cpp b/src/trel_dnssd/trel_dnssd.cpp new file mode 100644 index 00000000..daeb3e9b --- /dev/null +++ b/src/trel_dnssd/trel_dnssd.cpp @@ -0,0 +1,522 @@ +/* + * Copyright (c) 2021, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file includes implementation of TREL DNS-SD over mDNS. + */ + +#if OTBR_ENABLE_TREL + +#define OTBR_LOG_TAG "TrelDns" + +#include "trel_dnssd/trel_dnssd.hpp" + +#include <inttypes.h> +#include <net/if.h> + +#include <openthread/instance.h> +#include <openthread/link.h> +#include <openthread/platform/trel.h> + +#include "common/code_utils.hpp" +#include "utils/hex.hpp" +#include "utils/string_utils.hpp" + +static const char kTrelServiceName[] = "_trel._udp"; + +static otbr::TrelDnssd::TrelDnssd *sTrelDnssd = nullptr; + +void trelDnssdInitialize(const char *aTrelNetif) +{ + sTrelDnssd->Initialize(aTrelNetif); +} + +void trelDnssdStartBrowse(void) +{ + sTrelDnssd->StartBrowse(); +} + +void trelDnssdStopBrowse(void) +{ + sTrelDnssd->StopBrowse(); +} + +void trelDnssdRegisterService(uint16_t aPort, const uint8_t *aTxtData, uint8_t aTxtLength) +{ + sTrelDnssd->RegisterService(aPort, aTxtData, aTxtLength); +} + +void trelDnssdRemoveService(void) +{ + sTrelDnssd->UnregisterService(); +} + +namespace otbr { + +namespace TrelDnssd { + +TrelDnssd::TrelDnssd(Ncp::ControllerOpenThread &aNcp, Mdns::Publisher &aPublisher) + : mPublisher(aPublisher) + , mNcp(aNcp) +{ + sTrelDnssd = this; +} + +void TrelDnssd::Initialize(std::string aTrelNetif) +{ + mTrelNetif = std::move(aTrelNetif); + + if (IsInitialized()) + { + otbrLogDebug("Initialized on netif \"%s\"", mTrelNetif.c_str()); + CheckTrelNetifReady(); + } + else + { + otbrLogDebug("Not initialized"); + } +} + +void TrelDnssd::StartBrowse(void) +{ + VerifyOrExit(IsInitialized()); + + otbrLogDebug("Start browsing %s services ...", kTrelServiceName); + + assert(mSubscriberId == 0); + mSubscriberId = mPublisher.AddSubscriptionCallbacks( + [this](const std::string &aType, const Mdns::Publisher::DiscoveredInstanceInfo &aInstanceInfo) { + OnTrelServiceInstanceResolved(aType, aInstanceInfo); + }, + /* aHostCallback */ nullptr); + + if (IsReady()) + { + mPublisher.SubscribeService(kTrelServiceName, /* aInstanceName */ ""); + } + +exit: + return; +} + +void TrelDnssd::StopBrowse(void) +{ + VerifyOrExit(IsInitialized()); + + otbrLogDebug("Stop browsing %s service.", kTrelServiceName); + assert(mSubscriberId > 0); + + mPublisher.RemoveSubscriptionCallbacks(mSubscriberId); + mSubscriberId = 0; + + if (IsReady()) + { + mPublisher.UnsubscribeService(kTrelServiceName, ""); + } + +exit: + return; +} + +void TrelDnssd::RegisterService(uint16_t aPort, const uint8_t *aTxtData, uint8_t aTxtLength) +{ + assert(aPort > 0); + assert(aTxtData != nullptr); + + VerifyOrExit(IsInitialized()); + + otbrLogDebug("Register %s service: port=%u, TXT=%d bytes", kTrelServiceName, aPort, aTxtLength); + otbrDump(OTBR_LOG_DEBUG, OTBR_LOG_TAG, "TXT", aTxtData, aTxtLength); + + if (mRegisterInfo.IsValid() && IsReady()) + { + UnpublishTrelService(); + } + + mRegisterInfo.Assign(aPort, aTxtData, aTxtLength); + + if (IsReady()) + { + PublishTrelService(); + } + +exit: + return; +} + +void TrelDnssd::UnregisterService(void) +{ + VerifyOrExit(IsInitialized()); + + otbrLogDebug("Remove %s service", kTrelServiceName); + assert(mRegisterInfo.IsValid()); + + if (IsReady()) + { + UnpublishTrelService(); + } + + mRegisterInfo.Clear(); + +exit: + return; +} + +void TrelDnssd::OnMdnsPublisherReady(void) +{ + VerifyOrExit(IsInitialized()); + + otbrLogDebug("mDNS Publisher is Ready"); + mMdnsPublisherReady = true; + RemoveAllPeers(); + + if (mRegisterInfo.IsPublished()) + { + mRegisterInfo.mInstanceName = ""; + } + + OnBecomeReady(); + +exit: + return; +} + +void TrelDnssd::OnTrelServiceInstanceResolved(const std::string & aType, + const Mdns::Publisher::DiscoveredInstanceInfo &aInstanceInfo) +{ + VerifyOrExit(StringUtils::EqualCaseInsensitive(aType, kTrelServiceName)); + VerifyOrExit(aInstanceInfo.mNetifIndex == mTrelNetifIndex); + + if (aInstanceInfo.mRemoved) + { + OnTrelServiceInstanceRemoved(aInstanceInfo.mName); + } + else + { + OnTrelServiceInstanceAdded(aInstanceInfo); + } + +exit: + return; +} + +std::string TrelDnssd::GetTrelInstanceName(void) +{ + const otExtAddress *extaddr = otLinkGetExtendedAddress(mNcp.GetInstance()); + std::string name; + char nameBuf[sizeof(otExtAddress) * 2 + 1]; + + Utils::Bytes2Hex(extaddr->m8, sizeof(otExtAddress), nameBuf); + name = StringUtils::ToLowercase(nameBuf); + + assert(name.length() == sizeof(otExtAddress) * 2); + + otbrLogDebug("Using instance name %s", name.c_str()); + return name; +} + +void TrelDnssd::PublishTrelService(void) +{ + assert(mRegisterInfo.IsValid()); + assert(!mRegisterInfo.IsPublished()); + assert(mTrelNetifIndex > 0); + + mRegisterInfo.mInstanceName = GetTrelInstanceName(); + mPublisher.PublishService(/* aHostName */ "", mRegisterInfo.mInstanceName, kTrelServiceName, + Mdns::Publisher::SubTypeList{}, mRegisterInfo.mPort, mRegisterInfo.mTxtEntries, + [](otbrError aError) { HandlePublishTrelServiceError(aError); }); +} + +void TrelDnssd::HandlePublishTrelServiceError(otbrError aError) +{ + if (aError != OTBR_ERROR_NONE) + { + otbrLogErr("Failed to publish TREL service: %s. TREL won't be working.", otbrErrorString(aError)); + } +} + +void TrelDnssd::UnpublishTrelService(void) +{ + assert(mRegisterInfo.IsValid()); + assert(mRegisterInfo.IsPublished()); + + mPublisher.UnpublishService(mRegisterInfo.mInstanceName, kTrelServiceName, + [](otbrError aError) { HandleUnpublishTrelServiceError(aError); }); + mRegisterInfo.mInstanceName = ""; +} + +void TrelDnssd::HandleUnpublishTrelServiceError(otbrError aError) +{ + if (aError != OTBR_ERROR_NONE) + { + otbrLogInfo("Failed to unpublish TREL service: %s", otbrErrorString(aError)); + } +} + +void TrelDnssd::OnTrelServiceInstanceAdded(const Mdns::Publisher::DiscoveredInstanceInfo &aInstanceInfo) +{ + std::string instanceName = StringUtils::ToLowercase(aInstanceInfo.mName); + otPlatTrelPeerInfo peerInfo; + + // Remove any existing TREL service instance before adding + OnTrelServiceInstanceRemoved(instanceName); + + otbrLogDebug("Peer discovered: %s hostname %s addresses %zu port %d priority %d " + "weight %d", + aInstanceInfo.mName.c_str(), aInstanceInfo.mHostName.c_str(), aInstanceInfo.mAddresses.size(), + aInstanceInfo.mPort, aInstanceInfo.mPriority, aInstanceInfo.mWeight); + + for (const auto &addr : aInstanceInfo.mAddresses) + { + otbrLogDebug("Peer address: %s", addr.ToString().c_str()); + } + + if (aInstanceInfo.mAddresses.empty()) + { + otbrLogWarning("Peer %s does not have any IPv6 address, ignored", aInstanceInfo.mName.c_str()); + ExitNow(); + } + + peerInfo.mRemoved = false; + memcpy(&peerInfo.mSockAddr.mAddress, &aInstanceInfo.mAddresses[0], sizeof(peerInfo.mSockAddr.mAddress)); + peerInfo.mSockAddr.mPort = aInstanceInfo.mPort; + peerInfo.mTxtData = aInstanceInfo.mTxtData.data(); + peerInfo.mTxtLength = aInstanceInfo.mTxtData.size(); + + { + Peer peer(aInstanceInfo.mTxtData, peerInfo.mSockAddr); + + VerifyOrExit(peer.mValid, otbrLogWarning("Peer %s is invalid", aInstanceInfo.mName.c_str())); + + otPlatTrelHandleDiscoveredPeerInfo(mNcp.GetInstance(), &peerInfo); + + mPeers.emplace(instanceName, peer); + CheckPeersNumLimit(); + } + +exit: + return; +} + +void TrelDnssd::OnTrelServiceInstanceRemoved(const std::string &aInstanceName) +{ + std::string instanceName = StringUtils::ToLowercase(aInstanceName); + auto it = mPeers.find(instanceName); + + VerifyOrExit(it != mPeers.end()); + + otbrLogDebug("Peer removed: %s", instanceName.c_str()); + + // Remove the peer only when all instances are removed because one peer can have multiple instances if expired + // instances were not properly removed by mDNS. + if (CountDuplicatePeers(it->second) == 0) + { + NotifyRemovePeer(it->second); + } + + mPeers.erase(it); + +exit: + return; +} + +void TrelDnssd::CheckPeersNumLimit(void) +{ + const PeerMap::value_type *oldestPeer = nullptr; + + VerifyOrExit(mPeers.size() >= kPeerCacheSize); + + for (const auto &entry : mPeers) + { + if (oldestPeer == nullptr || entry.second.mDiscoverTime < oldestPeer->second.mDiscoverTime) + { + oldestPeer = &entry; + } + } + + OnTrelServiceInstanceRemoved(oldestPeer->first); + +exit: + return; +} + +void TrelDnssd::NotifyRemovePeer(const Peer &aPeer) +{ + otPlatTrelPeerInfo peerInfo; + + peerInfo.mRemoved = true; + peerInfo.mTxtData = aPeer.mTxtData.data(); + peerInfo.mTxtLength = aPeer.mTxtData.size(); + peerInfo.mSockAddr = aPeer.mSockAddr; + + otPlatTrelHandleDiscoveredPeerInfo(mNcp.GetInstance(), &peerInfo); +} + +void TrelDnssd::RemoveAllPeers(void) +{ + for (const auto &entry : mPeers) + { + NotifyRemovePeer(entry.second); + } + + mPeers.clear(); +} + +void TrelDnssd::CheckTrelNetifReady(void) +{ + assert(IsInitialized()); + + if (mTrelNetifIndex == 0) + { + mTrelNetifIndex = if_nametoindex(mTrelNetif.c_str()); + + if (mTrelNetifIndex != 0) + { + otbrLogDebug("Netif %s is ready: index = %" PRIu32, mTrelNetif.c_str(), mTrelNetifIndex); + OnBecomeReady(); + } + else + { + uint16_t delay = kCheckNetifReadyIntervalMs; + + otbrLogWarning("Netif %s is not ready (%s), will retry after %d seconds", mTrelNetif.c_str(), + strerror(errno), delay / 1000); + mTaskRunner.Post(Milliseconds(delay), [this]() { CheckTrelNetifReady(); }); + } + } +} + +bool TrelDnssd::IsReady(void) const +{ + assert(IsInitialized()); + + return mTrelNetifIndex > 0 && mMdnsPublisherReady; +} + +void TrelDnssd::OnBecomeReady(void) +{ + if (IsReady()) + { + otbrLogInfo("TREL DNS-SD Is Now Ready: Netif=%s(%" PRIu32 "), SubscriberId=%" PRIu64 ", Register=%s!", + mTrelNetif.c_str(), mTrelNetifIndex, mSubscriberId, mRegisterInfo.mInstanceName.c_str()); + + if (mSubscriberId > 0) + { + mPublisher.SubscribeService(kTrelServiceName, /* aInstanceName */ ""); + } + + if (mRegisterInfo.IsValid()) + { + PublishTrelService(); + } + } +} + +uint16_t TrelDnssd::CountDuplicatePeers(const TrelDnssd::Peer &aPeer) +{ + uint16_t count = 0; + + for (const auto &entry : mPeers) + { + if (&entry.second == &aPeer) + { + continue; + } + + if (!memcmp(&entry.second.mSockAddr, &aPeer.mSockAddr, sizeof(otSockAddr)) && + !memcmp(&entry.second.mExtAddr, &aPeer.mExtAddr, sizeof(otExtAddress))) + { + count++; + } + } + + return count; +} + +void TrelDnssd::RegisterInfo::Assign(uint16_t aPort, const uint8_t *aTxtData, uint8_t aTxtLength) +{ + otbrError error; + + OTBR_UNUSED_VARIABLE(error); + + assert(!IsPublished()); + assert(aPort > 0); + + mPort = aPort; + mTxtEntries.clear(); + + error = Mdns::Publisher::DecodeTxtData(mTxtEntries, aTxtData, aTxtLength); + assert(error == OTBR_ERROR_NONE); +} + +void TrelDnssd::RegisterInfo::Clear(void) +{ + assert(!IsPublished()); + + mPort = 0; + mTxtEntries.clear(); +} + +const char TrelDnssd::Peer::kTxtRecordExtAddressKey[] = "xa"; + +void TrelDnssd::Peer::ReadExtAddrFromTxtData(void) +{ + std::vector<Mdns::Publisher::TxtEntry> txtEntries; + + memset(&mExtAddr, 0, sizeof(mExtAddr)); + + SuccessOrExit(Mdns::Publisher::DecodeTxtData(txtEntries, mTxtData.data(), mTxtData.size())); + + for (const auto &txtEntry : txtEntries) + { + if (StringUtils::EqualCaseInsensitive(txtEntry.mName, kTxtRecordExtAddressKey)) + { + VerifyOrExit(txtEntry.mValue.size() == sizeof(mExtAddr)); + + memcpy(mExtAddr.m8, txtEntry.mValue.data(), sizeof(mExtAddr)); + mValid = true; + break; + } + } + +exit: + + if (!mValid) + { + otbrLogInfo("Failed to dissect ExtAddr from peer TXT data"); + } + + return; +} + +} // namespace TrelDnssd + +} // namespace otbr + +#endif // OTBR_ENABLE_TREL diff --git a/src/trel_dnssd/trel_dnssd.hpp b/src/trel_dnssd/trel_dnssd.hpp new file mode 100644 index 00000000..cf6564dc --- /dev/null +++ b/src/trel_dnssd/trel_dnssd.hpp @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2021, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file includes definitions for TREL DNS-SD over mDNS. + */ + +#ifndef OTBR_AGENT_TREL_DNSSD_HPP_ +#define OTBR_AGENT_TREL_DNSSD_HPP_ + +#if OTBR_ENABLE_TREL + +#include <assert.h> +#include <utility> + +#include <openthread/instance.h> + +#include "common/types.hpp" +#include "mdns/mdns.hpp" +#include "ncp/ncp_openthread.hpp" + +namespace otbr { + +namespace TrelDnssd { + +/** + * @addtogroup border-router-trel-dnssd + * + * @brief + * This module includes definition for TREL DNS-SD over mDNS. + * + * @{ + */ + +class TrelDnssd +{ +public: + /** + * This constructor initializes the TrelDnssd instance. + * + * @param[in] aNcp A reference to the OpenThread Controller instance. + * @param[in] aPublisher A reference to the mDNS Publisher. + * + */ + explicit TrelDnssd(Ncp::ControllerOpenThread &aNcp, Mdns::Publisher &aPublisher); + + /** + * This method initializes the TrelDnssd instance. + * + * @param[in] aTrelNetif The network interface for discovering TREL peers. + * + */ + void Initialize(std::string aTrelNetif); + + /** + * This method starts browsing for TREL peers. + * + */ + void StartBrowse(void); + + /** + * This method stops browsing for TREL peers. + * + */ + void StopBrowse(void); + + /** + * This method registers the TREL service to DNS-SD. + * + * @param[in] aPort The UDP port of TREL service. + * @param[in] aTxtData The TXT data of TREL service. + * @param[in] aTxtLength The TXT length of TREL service. + * + */ + void RegisterService(uint16_t aPort, const uint8_t *aTxtData, uint8_t aTxtLength); + + /** + * This method removes the TREL service from DNS-SD. + * + */ + void UnregisterService(void); + + /** + * This method notifies that mDNS Publisher is ready. + * + */ + void OnMdnsPublisherReady(void); + +private: + static constexpr size_t kPeerCacheSize = 256; + static constexpr uint16_t kCheckNetifReadyIntervalMs = 5000; + + struct RegisterInfo + { + uint16_t mPort = 0; + std::vector<Mdns::Publisher::TxtEntry> mTxtEntries; + std::string mInstanceName; + + bool IsValid(void) const { return mPort > 0; } + bool IsPublished(void) const { return !mInstanceName.empty(); } + void Assign(uint16_t aPort, const uint8_t *aTxtData, uint8_t aTxtLength); + void Clear(void); + }; + + using Clock = std::chrono::system_clock; + + struct Peer + { + static const char kTxtRecordExtAddressKey[]; + + explicit Peer(std::vector<uint8_t> aTxtData, const otSockAddr &aSockAddr) + : mDiscoverTime(Clock::now()) + , mTxtData(std::move(aTxtData)) + , mSockAddr(aSockAddr) + { + ReadExtAddrFromTxtData(); + } + + void ReadExtAddrFromTxtData(void); + + Clock::time_point mDiscoverTime; + std::vector<uint8_t> mTxtData; + otSockAddr mSockAddr; + otExtAddress mExtAddr; + bool mValid = false; + }; + + using PeerMap = std::map<std::string, Peer>; + + bool IsInitialized(void) const { return !mTrelNetif.empty(); } + bool IsReady(void) const; + void OnBecomeReady(void); + void CheckTrelNetifReady(void); + std::string GetTrelInstanceName(void); + void PublishTrelService(void); + void UnpublishTrelService(void); + static void HandlePublishTrelServiceError(otbrError aError); + static void HandleUnpublishTrelServiceError(otbrError aError); + void OnTrelServiceInstanceResolved(const std::string & aType, + const Mdns::Publisher::DiscoveredInstanceInfo &aInstanceInfo); + void OnTrelServiceInstanceAdded(const Mdns::Publisher::DiscoveredInstanceInfo &aInstanceInfo); + void OnTrelServiceInstanceRemoved(const std::string &aInstanceName); + + void NotifyRemovePeer(const Peer &aPeer); + void CheckPeersNumLimit(void); + void RemoveAllPeers(void); + uint16_t CountDuplicatePeers(const Peer &aPeer); + + Mdns::Publisher & mPublisher; + Ncp::ControllerOpenThread &mNcp; + TaskRunner mTaskRunner; + std::string mTrelNetif; + uint32_t mTrelNetifIndex = 0; + uint64_t mSubscriberId = 0; + RegisterInfo mRegisterInfo; + PeerMap mPeers; + bool mMdnsPublisherReady = false; +}; + +/** + * @} + */ + +} // namespace TrelDnssd + +} // namespace otbr + +#endif // OTBR_ENABLE_TREL + +#endif // OTBR_AGENT_TREL_DNSSD_HPP_ |