| /* |
| * Copyright (c) 2017, 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 mDNS publisher. |
| */ |
| |
| #ifndef OTBR_AGENT_MDNS_HPP_ |
| #define OTBR_AGENT_MDNS_HPP_ |
| |
| #include "openthread-br/config.h" |
| |
| #ifndef OTBR_ENABLE_MDNS |
| #define OTBR_ENABLE_MDNS (OTBR_ENABLE_MDNS_AVAHI || OTBR_ENABLE_MDNS_MDNSSD) |
| #endif |
| |
| #include <functional> |
| #include <list> |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include <sys/select.h> |
| |
| #include "common/callback.hpp" |
| #include "common/code_utils.hpp" |
| #include "common/time.hpp" |
| #include "common/types.hpp" |
| |
| namespace otbr { |
| |
| namespace Mdns { |
| |
| /** |
| * @addtogroup border-router-mdns |
| * |
| * @brief |
| * This module includes definition for mDNS publisher. |
| * |
| * @{ |
| */ |
| |
| /** |
| * This interface defines the functionality of mDNS publisher. |
| */ |
| class Publisher : private NonCopyable |
| { |
| public: |
| /** |
| * This structure represents a key/value pair of the TXT record. |
| */ |
| struct TxtEntry |
| { |
| std::string mKey; ///< The key of the TXT entry. |
| std::vector<uint8_t> mValue; ///< The value of the TXT entry. Can be empty. |
| bool mIsBooleanAttribute; ///< This entry is boolean attribute (encoded as `key` without `=`). |
| |
| TxtEntry(const char *aKey, const char *aValue) |
| : TxtEntry(aKey, reinterpret_cast<const uint8_t *>(aValue), strlen(aValue)) |
| { |
| } |
| |
| TxtEntry(const char *aKey, const uint8_t *aValue, size_t aValueLength) |
| : TxtEntry(aKey, strlen(aKey), aValue, aValueLength) |
| { |
| } |
| |
| TxtEntry(const char *aKey, size_t aKeyLength, const uint8_t *aValue, size_t aValueLength) |
| : mKey(aKey, aKeyLength) |
| , mValue(aValue, aValue + aValueLength) |
| , mIsBooleanAttribute(false) |
| { |
| } |
| |
| TxtEntry(const char *aKey) |
| : TxtEntry(aKey, strlen(aKey)) |
| { |
| } |
| |
| TxtEntry(const char *aKey, size_t aKeyLength) |
| : mKey(aKey, aKeyLength) |
| , mIsBooleanAttribute(true) |
| { |
| } |
| |
| bool operator==(const TxtEntry &aOther) const |
| { |
| return (mKey == aOther.mKey) && (mValue == aOther.mValue) && |
| (mIsBooleanAttribute == aOther.mIsBooleanAttribute); |
| } |
| }; |
| |
| typedef std::vector<uint8_t> TxtData; |
| typedef std::vector<TxtEntry> TxtList; |
| typedef std::vector<std::string> SubTypeList; |
| typedef std::vector<Ip6Address> AddressList; |
| typedef std::vector<uint8_t> KeyData; |
| |
| /** |
| * This structure represents information of a discovered service instance. |
| */ |
| struct DiscoveredInstanceInfo |
| { |
| bool mRemoved = false; ///< The Service Instance is removed. |
| uint32_t mNetifIndex = 0; ///< Network interface. |
| std::string mName; ///< Instance name. |
| std::string mHostName; ///< Full host name. |
| AddressList mAddresses; ///< IPv6 addresses. |
| uint16_t mPort = 0; ///< Port. |
| uint16_t mPriority = 0; ///< Service priority. |
| uint16_t mWeight = 0; ///< Service weight. |
| TxtData mTxtData; ///< TXT RDATA bytes. |
| uint32_t mTtl = 0; ///< Service TTL. |
| |
| void AddAddress(const Ip6Address &aAddress) { Publisher::AddAddress(mAddresses, aAddress); } |
| void RemoveAddress(const Ip6Address &aAddress) { Publisher::RemoveAddress(mAddresses, aAddress); } |
| }; |
| |
| /** |
| * This structure represents information of a discovered host. |
| */ |
| struct DiscoveredHostInfo |
| { |
| std::string mHostName; ///< Full host name. |
| AddressList mAddresses; ///< IP6 addresses. |
| uint32_t mNetifIndex = 0; ///< Network interface. |
| uint32_t mTtl = 0; ///< Host TTL. |
| |
| void AddAddress(const Ip6Address &aAddress) { Publisher::AddAddress(mAddresses, aAddress); } |
| void RemoveAddress(const Ip6Address &aAddress) { Publisher::RemoveAddress(mAddresses, aAddress); } |
| }; |
| |
| /** |
| * This function is called to notify a discovered service instance. |
| */ |
| using DiscoveredServiceInstanceCallback = |
| std::function<void(const std::string &aType, const DiscoveredInstanceInfo &aInstanceInfo)>; |
| |
| /** |
| * This function is called to notify a discovered host. |
| */ |
| using DiscoveredHostCallback = |
| std::function<void(const std::string &aHostName, const DiscoveredHostInfo &aHostInfo)>; |
| |
| /** |
| * mDNS state values. |
| */ |
| enum class State |
| { |
| kIdle, ///< Unable to publish service. |
| kReady, ///< Ready to publish service. |
| }; |
| |
| /** The callback for receiving mDNS publisher state changes. */ |
| using StateCallback = std::function<void(State aNewState)>; |
| |
| /** The callback for receiving the result of a operation. */ |
| using ResultCallback = OnceCallback<void(otbrError aError)>; |
| |
| /** |
| * This method starts the mDNS publisher. |
| * |
| * @retval OTBR_ERROR_NONE Successfully started mDNS publisher; |
| * @retval OTBR_ERROR_MDNS Failed to start mDNS publisher. |
| */ |
| virtual otbrError Start(void) = 0; |
| |
| /** |
| * This method stops the mDNS publisher. |
| */ |
| virtual void Stop(void) = 0; |
| |
| /** |
| * This method checks if publisher has been started. |
| * |
| * @retval true Already started. |
| * @retval false Not started. |
| */ |
| virtual bool IsStarted(void) const = 0; |
| |
| /** |
| * This method publishes or updates a service. |
| * |
| * @param[in] aHostName The name of the host which this service resides on. If an empty string is |
| * provided, this service resides on local host and it is the implementation |
| * to provide specific host name. Otherwise, the caller MUST publish the host |
| * with method PublishHost. |
| * @param[in] aName The name of this service. If an empty string is provided, the service's name will be the |
| * same as the platform's hostname. |
| * @param[in] aType The type of this service, e.g., "_srv._udp" (MUST NOT end with dot). |
| * @param[in] aSubTypeList A list of service subtypes. |
| * @param[in] aPort The port number of this service. |
| * @param[in] aTxtData The encoded TXT data for this service. |
| * @param[in] aCallback The callback for receiving the publishing result. `OTBR_ERROR_NONE` will be |
| * returned if the operation is successful and all other values indicate a |
| * failure. Specifically, `OTBR_ERROR_DUPLICATED` indicates that the name has |
| * already been published and the caller can re-publish with a new name if an |
| * alternative name is available/acceptable. |
| */ |
| void PublishService(const std::string &aHostName, |
| const std::string &aName, |
| const std::string &aType, |
| const SubTypeList &aSubTypeList, |
| uint16_t aPort, |
| const TxtData &aTxtData, |
| ResultCallback &&aCallback); |
| |
| /** |
| * This method un-publishes a service. |
| * |
| * @param[in] aName The name of this service. |
| * @param[in] aType The type of this service, e.g., "_srv._udp" (MUST NOT end with dot). |
| * @param[in] aCallback The callback for receiving the publishing result. |
| */ |
| virtual void UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) = 0; |
| |
| /** |
| * This method publishes or updates a host. |
| * |
| * Publishing a host is advertising an AAAA RR for the host name. This method should be called |
| * before a service with non-empty host name is published. |
| * |
| * @param[in] aName The name of the host. |
| * @param[in] aAddresses The addresses of the host. |
| * @param[in] aCallback The callback for receiving the publishing result.`OTBR_ERROR_NONE` will be |
| * returned if the operation is successful and all other values indicate a |
| * failure. Specifically, `OTBR_ERROR_DUPLICATED` indicates that the name has |
| * already been published and the caller can re-publish with a new name if an |
| * alternative name is available/acceptable. |
| */ |
| void PublishHost(const std::string &aName, const AddressList &aAddresses, ResultCallback &&aCallback); |
| |
| /** |
| * This method un-publishes a host. |
| * |
| * @param[in] aName A host name (MUST not end with dot). |
| * @param[in] aCallback The callback for receiving the publishing result. |
| */ |
| virtual void UnpublishHost(const std::string &aName, ResultCallback &&aCallback) = 0; |
| |
| /** |
| * This method publishes or updates a key record for a name. |
| * |
| * @param[in] aName The name associated with key record (can be host name or service instance name). |
| * @param[in] aKeyData The key data to publish. |
| * @param[in] aCallback The callback for receiving the publishing result.`OTBR_ERROR_NONE` will be |
| * returned if the operation is successful and all other values indicate a |
| * failure. Specifically, `OTBR_ERROR_DUPLICATED` indicates that the name has |
| * already been published and the caller can re-publish with a new name if an |
| * alternative name is available/acceptable. |
| */ |
| void PublishKey(const std::string &aName, const KeyData &aKeyData, ResultCallback &&aCallback); |
| |
| /** |
| * This method un-publishes a key record |
| * |
| * @param[in] aName The name associated with key record. |
| * @param[in] aCallback The callback for receiving the publishing result. |
| */ |
| virtual void UnpublishKey(const std::string &aName, ResultCallback &&aCallback) = 0; |
| |
| /** |
| * This method subscribes a given service or service instance. |
| * |
| * If @p aInstanceName is not empty, this method subscribes the service instance. Otherwise, this method subscribes |
| * the service. mDNS implementations should use the `DiscoveredServiceInstanceCallback` function to notify |
| * discovered service instances. |
| * |
| * @note Discovery Proxy implementation guarantees no duplicate subscriptions for the same service or service |
| * instance. |
| * |
| * @param[in] aType The service type, e.g., "_srv._udp" (MUST NOT end with dot). |
| * @param[in] aInstanceName The service instance to subscribe, or empty to subscribe the service. |
| */ |
| virtual void SubscribeService(const std::string &aType, const std::string &aInstanceName) = 0; |
| |
| /** |
| * This method unsubscribes a given service or service instance. |
| * |
| * If @p aInstanceName is not empty, this method unsubscribes the service instance. Otherwise, this method |
| * unsubscribes the service. |
| * |
| * @note Discovery Proxy implementation guarantees no redundant unsubscription for a service or service instance. |
| * |
| * @param[in] aType The service type, e.g., "_srv._udp" (MUST NOT end with dot). |
| * @param[in] aInstanceName The service instance to unsubscribe, or empty to unsubscribe the service. |
| */ |
| virtual void UnsubscribeService(const std::string &aType, const std::string &aInstanceName) = 0; |
| |
| /** |
| * This method subscribes a given host. |
| * |
| * mDNS implementations should use the `DiscoveredHostCallback` function to notify discovered hosts. |
| * |
| * @note Discovery Proxy implementation guarantees no duplicate subscriptions for the same host. |
| * |
| * @param[in] aHostName The host name (without domain). |
| */ |
| virtual void SubscribeHost(const std::string &aHostName) = 0; |
| |
| /** |
| * This method unsubscribes a given host. |
| * |
| * @note Discovery Proxy implementation guarantees no redundant unsubscription for a host. |
| * |
| * @param[in] aHostName The host name (without domain). |
| */ |
| virtual void UnsubscribeHost(const std::string &aHostName) = 0; |
| |
| /** |
| * This method sets the callbacks for subscriptions. |
| * |
| * @param[in] aInstanceCallback The callback function to receive discovered service instances. |
| * @param[in] aHostCallback The callback function to receive discovered hosts. |
| * |
| * @returns The Subscriber ID for the callbacks. |
| */ |
| uint64_t AddSubscriptionCallbacks(DiscoveredServiceInstanceCallback aInstanceCallback, |
| DiscoveredHostCallback aHostCallback); |
| |
| /** |
| * This method cancels callbacks for subscriptions. |
| * |
| * @param[in] aSubscriberId The Subscriber ID previously returned by `AddSubscriptionCallbacks`. |
| */ |
| void RemoveSubscriptionCallbacks(uint64_t aSubscriberId); |
| |
| /** |
| * This method returns the mDNS statistics information of the publisher. |
| * |
| * @returns The MdnsTelemetryInfo of the publisher. |
| */ |
| const MdnsTelemetryInfo &GetMdnsTelemetryInfo(void) const { return mTelemetryInfo; } |
| |
| virtual ~Publisher(void) = default; |
| |
| /** |
| * This function creates a mDNS publisher. |
| * |
| * @param[in] aCallback The callback for receiving mDNS publisher state changes. |
| * |
| * @returns A pointer to the newly created mDNS publisher. |
| */ |
| static Publisher *Create(StateCallback aCallback); |
| |
| /** |
| * This function destroys the mDNS publisher. |
| * |
| * @param[in] aPublisher A pointer to the publisher. |
| */ |
| static void Destroy(Publisher *aPublisher); |
| |
| /** |
| * This function writes the TXT entry list to a TXT data buffer. The TXT entries |
| * will be sorted by their keys. |
| * |
| * The output data is in standard DNS-SD TXT data format. |
| * See RFC 6763 for details: https://tools.ietf.org/html/rfc6763#section-6. |
| * |
| * @param[in] aTxtList A TXT entry list. |
| * @param[out] aTxtData A TXT data buffer. Will be cleared. |
| * |
| * @retval OTBR_ERROR_NONE Successfully write the TXT entry list. |
| * @retval OTBR_ERROR_INVALID_ARGS The @p aTxtList includes invalid TXT entry. |
| * |
| * @sa DecodeTxtData |
| */ |
| static otbrError EncodeTxtData(const TxtList &aTxtList, TxtData &aTxtData); |
| |
| /** |
| * This function decodes a TXT entry list from a TXT data buffer. |
| * |
| * The input data should be in standard DNS-SD TXT data format. |
| * See RFC 6763 for details: https://tools.ietf.org/html/rfc6763#section-6. |
| * |
| * @param[out] aTxtList A TXT entry list. |
| * @param[in] aTxtData A pointer to TXT data. |
| * @param[in] aTxtLength The TXT data length. |
| * |
| * @retval OTBR_ERROR_NONE Successfully decoded the TXT data. |
| * @retval OTBR_ERROR_INVALID_ARGS The @p aTxtdata has invalid TXT format. |
| * |
| * @sa EncodeTxtData |
| */ |
| static otbrError DecodeTxtData(TxtList &aTxtList, const uint8_t *aTxtData, uint16_t aTxtLength); |
| |
| protected: |
| static constexpr uint8_t kMaxTextEntrySize = 255; |
| |
| class Registration |
| { |
| public: |
| ResultCallback mCallback; |
| Publisher *mPublisher; |
| |
| Registration(ResultCallback &&aCallback, Publisher *aPublisher) |
| : mCallback(std::move(aCallback)) |
| , mPublisher(aPublisher) |
| { |
| } |
| virtual ~Registration(void); |
| |
| // Tells whether the service registration has been completed (typically by calling |
| // `ServiceRegistration::Complete`). |
| bool IsCompleted() const { return mCallback.IsNull(); } |
| |
| protected: |
| // Completes the service registration with given result/error. |
| void TriggerCompleteCallback(otbrError aError) |
| { |
| if (!IsCompleted()) |
| { |
| std::move(mCallback)(aError); |
| } |
| } |
| }; |
| |
| // TODO: We may need a registration ID to fetch the information of a registration. |
| class ServiceRegistration : public Registration |
| { |
| public: |
| std::string mHostName; |
| std::string mName; |
| std::string mType; |
| SubTypeList mSubTypeList; |
| uint16_t mPort; |
| TxtData mTxtData; |
| |
| ServiceRegistration(std::string aHostName, |
| std::string aName, |
| std::string aType, |
| SubTypeList aSubTypeList, |
| uint16_t aPort, |
| TxtData aTxtData, |
| ResultCallback &&aCallback, |
| Publisher *aPublisher) |
| : Registration(std::move(aCallback), aPublisher) |
| , mHostName(std::move(aHostName)) |
| , mName(std::move(aName)) |
| , mType(std::move(aType)) |
| , mSubTypeList(SortSubTypeList(std::move(aSubTypeList))) |
| , mPort(aPort) |
| , mTxtData(std::move(aTxtData)) |
| { |
| } |
| ~ServiceRegistration(void) override { OnComplete(OTBR_ERROR_ABORTED); } |
| |
| void Complete(otbrError aError); |
| |
| // Tells whether this `ServiceRegistration` object is outdated comparing to the given parameters. |
| bool IsOutdated(const std::string &aHostName, |
| const std::string &aName, |
| const std::string &aType, |
| const SubTypeList &aSubTypeList, |
| uint16_t aPort, |
| const TxtData &aTxtData) const; |
| |
| private: |
| void OnComplete(otbrError aError); |
| }; |
| |
| class HostRegistration : public Registration |
| { |
| public: |
| std::string mName; |
| AddressList mAddresses; |
| |
| HostRegistration(std::string aName, AddressList aAddresses, ResultCallback &&aCallback, Publisher *aPublisher) |
| : Registration(std::move(aCallback), aPublisher) |
| , mName(std::move(aName)) |
| , mAddresses(SortAddressList(std::move(aAddresses))) |
| { |
| } |
| |
| ~HostRegistration(void) override { OnComplete(OTBR_ERROR_ABORTED); } |
| |
| void Complete(otbrError aError); |
| |
| // Tells whether this `HostRegistration` object is outdated comparing to the given parameters. |
| bool IsOutdated(const std::string &aName, const AddressList &aAddresses) const; |
| |
| private: |
| void OnComplete(otbrError aError); |
| }; |
| |
| class KeyRegistration : public Registration |
| { |
| public: |
| std::string mName; |
| KeyData mKeyData; |
| |
| KeyRegistration(std::string aName, KeyData aKeyData, ResultCallback &&aCallback, Publisher *aPublisher) |
| : Registration(std::move(aCallback), aPublisher) |
| , mName(std::move(aName)) |
| , mKeyData(std::move(aKeyData)) |
| { |
| } |
| |
| ~KeyRegistration(void) { OnComplete(OTBR_ERROR_ABORTED); } |
| |
| void Complete(otbrError aError); |
| |
| // Tells whether this `KeyRegistration` object is outdated comparing to the given parameters. |
| bool IsOutdated(const std::string &aName, const KeyData &aKeyData) const; |
| |
| private: |
| void OnComplete(otbrError aError); |
| }; |
| |
| using ServiceRegistrationPtr = std::unique_ptr<ServiceRegistration>; |
| using ServiceRegistrationMap = std::map<std::string, ServiceRegistrationPtr>; |
| using HostRegistrationPtr = std::unique_ptr<HostRegistration>; |
| using HostRegistrationMap = std::map<std::string, HostRegistrationPtr>; |
| using KeyRegistrationPtr = std::unique_ptr<KeyRegistration>; |
| using KeyRegistrationMap = std::map<std::string, KeyRegistrationPtr>; |
| |
| static SubTypeList SortSubTypeList(SubTypeList aSubTypeList); |
| static AddressList SortAddressList(AddressList aAddressList); |
| static std::string MakeFullName(const std::string &aName); |
| static std::string MakeFullServiceName(const std::string &aName, const std::string &aType); |
| static std::string MakeFullHostName(const std::string &aName) { return MakeFullName(aName); } |
| static std::string MakeFullKeyName(const std::string &aName) { return MakeFullName(aName); } |
| |
| virtual otbrError PublishServiceImpl(const std::string &aHostName, |
| const std::string &aName, |
| const std::string &aType, |
| const SubTypeList &aSubTypeList, |
| uint16_t aPort, |
| const TxtData &aTxtData, |
| ResultCallback &&aCallback) = 0; |
| |
| virtual otbrError PublishHostImpl(const std::string &aName, |
| const AddressList &aAddresses, |
| ResultCallback &&aCallback) = 0; |
| |
| virtual otbrError PublishKeyImpl(const std::string &aName, const KeyData &aKeyData, ResultCallback &&aCallback) = 0; |
| |
| virtual void OnServiceResolveFailedImpl(const std::string &aType, |
| const std::string &aInstanceName, |
| int32_t aErrorCode) = 0; |
| |
| virtual void OnHostResolveFailedImpl(const std::string &aHostName, int32_t aErrorCode) = 0; |
| |
| virtual otbrError DnsErrorToOtbrError(int32_t aError) = 0; |
| |
| void AddServiceRegistration(ServiceRegistrationPtr &&aServiceReg); |
| void RemoveServiceRegistration(const std::string &aName, const std::string &aType, otbrError aError); |
| ServiceRegistration *FindServiceRegistration(const std::string &aName, const std::string &aType); |
| ServiceRegistration *FindServiceRegistration(const std::string &aNameAndType); |
| |
| void OnServiceResolved(std::string aType, DiscoveredInstanceInfo aInstanceInfo); |
| void OnServiceResolveFailed(std::string aType, std::string aInstanceName, int32_t aErrorCode); |
| void OnServiceRemoved(uint32_t aNetifIndex, std::string aType, std::string aInstanceName); |
| void OnHostResolved(std::string aHostName, DiscoveredHostInfo aHostInfo); |
| void OnHostResolveFailed(std::string aHostName, int32_t aErrorCode); |
| |
| // Handles the cases that there is already a registration for the same service. |
| // If the returned callback is completed, current registration should be considered |
| // success and no further action should be performed. |
| ResultCallback HandleDuplicateServiceRegistration(const std::string &aHostName, |
| const std::string &aName, |
| const std::string &aType, |
| const SubTypeList &aSubTypeList, |
| uint16_t aPort, |
| const TxtData &aTxtData, |
| ResultCallback &&aCallback); |
| |
| ResultCallback HandleDuplicateHostRegistration(const std::string &aName, |
| const AddressList &aAddresses, |
| ResultCallback &&aCallback); |
| |
| ResultCallback HandleDuplicateKeyRegistration(const std::string &aName, |
| const KeyData &aKeyData, |
| ResultCallback &&aCallback); |
| |
| void AddHostRegistration(HostRegistrationPtr &&aHostReg); |
| void RemoveHostRegistration(const std::string &aName, otbrError aError); |
| HostRegistration *FindHostRegistration(const std::string &aName); |
| |
| void AddKeyRegistration(KeyRegistrationPtr &&aKeyReg); |
| void RemoveKeyRegistration(const std::string &aName, otbrError aError); |
| KeyRegistration *FindKeyRegistration(const std::string &aName); |
| KeyRegistration *FindKeyRegistration(const std::string &aName, const std::string &aType); |
| |
| static void UpdateMdnsResponseCounters(MdnsResponseCounters &aCounters, otbrError aError); |
| static void UpdateEmaLatency(uint32_t &aEmaLatency, uint32_t aLatency, otbrError aError); |
| |
| void UpdateServiceRegistrationEmaLatency(const std::string &aInstanceName, |
| const std::string &aType, |
| otbrError aError); |
| void UpdateHostRegistrationEmaLatency(const std::string &aHostName, otbrError aError); |
| void UpdateKeyRegistrationEmaLatency(const std::string &aKeyName, otbrError aError); |
| void UpdateServiceInstanceResolutionEmaLatency(const std::string &aInstanceName, |
| const std::string &aType, |
| otbrError aError); |
| void UpdateHostResolutionEmaLatency(const std::string &aHostName, otbrError aError); |
| |
| static void AddAddress(AddressList &aAddressList, const Ip6Address &aAddress); |
| static void RemoveAddress(AddressList &aAddressList, const Ip6Address &aAddress); |
| |
| ServiceRegistrationMap mServiceRegistrations; |
| HostRegistrationMap mHostRegistrations; |
| KeyRegistrationMap mKeyRegistrations; |
| |
| struct DiscoverCallback |
| { |
| DiscoverCallback(uint64_t aId, |
| DiscoveredServiceInstanceCallback aServiceCallback, |
| DiscoveredHostCallback aHostCallback) |
| : mId(aId) |
| , mServiceCallback(std::move(aServiceCallback)) |
| , mHostCallback(std::move(aHostCallback)) |
| , mShouldInvoke(false) |
| { |
| } |
| |
| uint64_t mId; |
| DiscoveredServiceInstanceCallback mServiceCallback; |
| DiscoveredHostCallback mHostCallback; |
| bool mShouldInvoke; |
| }; |
| |
| uint64_t mNextSubscriberId = 1; |
| |
| std::list<DiscoverCallback> mDiscoverCallbacks; |
| |
| // {instance name, service type} -> the timepoint to begin service registration |
| std::map<std::pair<std::string, std::string>, Timepoint> mServiceRegistrationBeginTime; |
| // host name -> the timepoint to begin host registration |
| std::map<std::string, Timepoint> mHostRegistrationBeginTime; |
| // key name -> the timepoint to begin key registration |
| std::map<std::string, Timepoint> mKeyRegistrationBeginTime; |
| // {instance name, service type} -> the timepoint to begin service resolution |
| std::map<std::pair<std::string, std::string>, Timepoint> mServiceInstanceResolutionBeginTime; |
| // host name -> the timepoint to begin host resolution |
| std::map<std::string, Timepoint> mHostResolutionBeginTime; |
| |
| MdnsTelemetryInfo mTelemetryInfo{}; |
| }; |
| |
| /** |
| * This interface is a mDNS State Observer. |
| */ |
| class StateObserver |
| { |
| public: |
| /** |
| * This method notifies the mDNS state to the observer. |
| * |
| * @param[in] aState The mDNS State. |
| */ |
| virtual void HandleMdnsState(Publisher::State aState) = 0; |
| |
| /** |
| * The destructor. |
| */ |
| virtual ~StateObserver(void) = default; |
| }; |
| |
| /** |
| * This class defines a mDNS State Subject. |
| */ |
| class StateSubject |
| { |
| public: |
| /** |
| * Constructor. |
| */ |
| StateSubject(void) = default; |
| |
| /** |
| * Destructor. |
| */ |
| ~StateSubject(void) = default; |
| |
| /** |
| * This method adds an mDNS State Observer to this subject. |
| * |
| * @param[in] aObserver A reference to the observer. If it's nullptr, it won't be added. |
| */ |
| void AddObserver(StateObserver &aObserver); |
| |
| /** |
| * This method updates the mDNS State. |
| * |
| * @param[in] aState The mDNS State. |
| */ |
| void UpdateState(Publisher::State aState); |
| |
| /** |
| * This method removes all the observers. |
| */ |
| void Clear(void); |
| |
| private: |
| std::vector<StateObserver *> mObservers; |
| }; |
| |
| /** |
| * @} |
| */ |
| |
| } // namespace Mdns |
| |
| } // namespace otbr |
| |
| #endif // OTBR_AGENT_MDNS_HPP_ |