diff options
author | whd <7058128+superwhd@users.noreply.github.com> | 2022-06-28 11:29:00 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-27 20:29:00 -0700 |
commit | e4a197f3397024c3e02bc4dabded434ab865b2af (patch) | |
tree | 5ef27b733454e2a739788927552c229266c3a9eb /src | |
parent | 489f99934525294fa8b8818ac1f90be188839629 (diff) | |
download | ot-br-posix-e4a197f3397024c3e02bc4dabded434ab865b2af.tar.gz |
[dbus] add D-BUS API `GetMdnsInfo` (#1400)
Diffstat (limited to 'src')
-rw-r--r-- | src/agent/application.cpp | 4 | ||||
-rw-r--r-- | src/border_agent/border_agent.hpp | 8 | ||||
-rw-r--r-- | src/common/types.hpp | 30 | ||||
-rw-r--r-- | src/dbus/client/thread_api_dbus.cpp | 5 | ||||
-rw-r--r-- | src/dbus/client/thread_api_dbus.hpp | 12 | ||||
-rw-r--r-- | src/dbus/common/constants.hpp | 1 | ||||
-rw-r--r-- | src/dbus/common/dbus_message_helper.hpp | 14 | ||||
-rw-r--r-- | src/dbus/common/dbus_message_helper_openthread.cpp | 82 | ||||
-rw-r--r-- | src/dbus/server/dbus_agent.cpp | 9 | ||||
-rw-r--r-- | src/dbus/server/dbus_agent.hpp | 3 | ||||
-rw-r--r-- | src/dbus/server/dbus_thread_object.cpp | 16 | ||||
-rw-r--r-- | src/dbus/server/dbus_thread_object.hpp | 7 | ||||
-rw-r--r-- | src/dbus/server/introspect.xml | 46 | ||||
-rw-r--r-- | src/mdns/mdns.cpp | 170 | ||||
-rw-r--r-- | src/mdns/mdns.hpp | 107 | ||||
-rw-r--r-- | src/mdns/mdns_avahi.cpp | 86 | ||||
-rw-r--r-- | src/mdns/mdns_avahi.hpp | 47 | ||||
-rw-r--r-- | src/mdns/mdns_mdnssd.cpp | 50 | ||||
-rw-r--r-- | src/mdns/mdns_mdnssd.hpp | 52 |
19 files changed, 642 insertions, 107 deletions
diff --git a/src/agent/application.cpp b/src/agent/application.cpp index 35540ef0..1ddd4741 100644 --- a/src/agent/application.cpp +++ b/src/agent/application.cpp @@ -65,8 +65,8 @@ Application::Application(const std::string & aInterfaceName, #if OTBR_ENABLE_REST_SERVER , mRestWebServer(mNcp) #endif -#if OTBR_ENABLE_DBUS_SERVER - , mDBusAgent(mNcp) +#if OTBR_ENABLE_DBUS_SERVER && OTBR_ENABLE_BORDER_AGENT + , mDBusAgent(mNcp, mBorderAgent.GetPublisher()) #endif #if OTBR_ENABLE_VENDOR_SERVER , mVendorServer(mNcp) diff --git a/src/border_agent/border_agent.hpp b/src/border_agent/border_agent.hpp index 50f98995..580ff0a0 100644 --- a/src/border_agent/border_agent.hpp +++ b/src/border_agent/border_agent.hpp @@ -103,6 +103,14 @@ public: */ void Deinit(void); + /** + * This method returns the Publisher the border agent is using. + * + * @returns A reference to the mPublisher. + * + */ + Mdns::Publisher &GetPublisher() { return *mPublisher; } + private: enum : uint8_t { diff --git a/src/common/types.hpp b/src/common/types.hpp index 9f77e4ea..80eaa51f 100644 --- a/src/common/types.hpp +++ b/src/common/types.hpp @@ -379,6 +379,36 @@ public: }; }; +struct MdnsResponseCounters +{ + uint32_t mSuccess; ///< The number of successful responses + uint32_t mNotFound; ///< The number of 'not found' responses + uint32_t mInvalidArgs; ///< The number of 'invalid arg' responses + uint32_t mDuplicated; ///< The number of 'duplicated' responses + uint32_t mNotImplemented; ///< The number of 'not implemented' responses + uint32_t mUnknownError; ///< The number of unknown error responses +}; + +struct MdnsTelemetryInfo +{ + static constexpr uint32_t kEmaFactorNumerator = 1; + static constexpr uint32_t kEmaFactorDenominator = 2; + + static_assert(kEmaFactorNumerator > 0, "kEmaFactorNumerator must be greater than 0"); + static_assert(kEmaFactorDenominator > kEmaFactorNumerator, + "kEmaFactorDenominator must be greater than kEmaFactorNumerator"); + + MdnsResponseCounters mHostRegistrations; + MdnsResponseCounters mServiceRegistrations; + MdnsResponseCounters mHostResolutions; + MdnsResponseCounters mServiceResolutions; + + uint32_t mHostRegistrationEmaLatency; ///< The EMA latency of host registrations in milliseconds + uint32_t mServiceRegistrationEmaLatency; ///< The EMA latency of service registrations in milliseconds + uint32_t mHostResolutionEmaLatency; ///< The EMA latency of host resolutions in milliseconds + uint32_t mServiceResolutionEmaLatency; ///< The EMA latency of service resolutions in milliseconds +}; + } // namespace otbr #endif // OTBR_COMMON_TYPES_HPP_ diff --git a/src/dbus/client/thread_api_dbus.cpp b/src/dbus/client/thread_api_dbus.cpp index eef97000..cc9bb2be 100644 --- a/src/dbus/client/thread_api_dbus.cpp +++ b/src/dbus/client/thread_api_dbus.cpp @@ -638,6 +638,11 @@ ClientError ThreadApiDBus::GetSrpServerInfo(SrpServerInfo &aSrpServerInfo) return GetProperty(OTBR_DBUS_PROPERTY_SRP_SERVER_INFO, aSrpServerInfo); } +ClientError ThreadApiDBus::GetMdnsTelemetryInfo(MdnsTelemetryInfo &aMdnsTelemetryInfo) +{ + return GetProperty(OTBR_DBUS_PROPERTY_MDNS_TELEMETRY_INFO, aMdnsTelemetryInfo); +} + #if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY ClientError ThreadApiDBus::GetDnssdCounters(DnssdCounters &aDnssdCounters) { diff --git a/src/dbus/client/thread_api_dbus.hpp b/src/dbus/client/thread_api_dbus.hpp index f43e1b10..8ab2bcaf 100644 --- a/src/dbus/client/thread_api_dbus.hpp +++ b/src/dbus/client/thread_api_dbus.hpp @@ -717,6 +717,18 @@ public: */ ClientError GetSrpServerInfo(SrpServerInfo &aSrpServerInfo); + /** + * This method gets the MDNS telemetry information. + * + * @param[out] aMdnsTelemetryInfo The MDNS telemetry information. + * + * @retval ERROR_NONE Successfully performed the dbus function call + * @retval ERROR_DBUS dbus encode/decode error + * @retval ... OpenThread defined error value otherwise + * + */ + ClientError GetMdnsTelemetryInfo(MdnsTelemetryInfo &aMdnsTelemetryInfo); + #if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY /** * This method gets the DNS-SD counters. diff --git a/src/dbus/common/constants.hpp b/src/dbus/common/constants.hpp index 0aaf2d92..10d8fb56 100644 --- a/src/dbus/common/constants.hpp +++ b/src/dbus/common/constants.hpp @@ -98,6 +98,7 @@ #define OTBR_DBUS_PROPERTY_OT_RCP_VERSION "OtRcpVersion" #define OTBR_DBUS_PROPERTY_THREAD_VERSION "ThreadVersion" #define OTBR_DBUS_PROPERTY_EUI64 "Eui64" +#define OTBR_DBUS_PROPERTY_MDNS_TELEMETRY_INFO "MdnsTelemetryInfo" #define OTBR_ROLE_NAME_DISABLED "disabled" #define OTBR_ROLE_NAME_DETACHED "detached" diff --git a/src/dbus/common/dbus_message_helper.hpp b/src/dbus/common/dbus_message_helper.hpp index 2cb16322..9cc041e5 100644 --- a/src/dbus/common/dbus_message_helper.hpp +++ b/src/dbus/common/dbus_message_helper.hpp @@ -83,6 +83,10 @@ otbrError DBusMessageEncode(DBusMessageIter *aIter, const SrpServerInfo::Respons otbrError DBusMessageExtract(DBusMessageIter *aIter, SrpServerInfo::ResponseCounters &aResponseCounters); otbrError DBusMessageEncode(DBusMessageIter *aIter, const SrpServerInfo &aSrpServerInfo); otbrError DBusMessageExtract(DBusMessageIter *aIter, SrpServerInfo &aSrpServerInfo); +otbrError DBusMessageEncode(DBusMessageIter *aIter, const MdnsResponseCounters &aMdnsResponseCounters); +otbrError DBusMessageExtract(DBusMessageIter *aIter, MdnsResponseCounters &aMdnsResponseCounters); +otbrError DBusMessageEncode(DBusMessageIter *aIter, const MdnsTelemetryInfo &aMdnsTelemetryInfo); +otbrError DBusMessageExtract(DBusMessageIter *aIter, MdnsTelemetryInfo &aMdnsTelemetryInfo); otbrError DBusMessageEncode(DBusMessageIter *aIter, const DnssdCounters &aDnssdCounters); otbrError DBusMessageExtract(DBusMessageIter *aIter, DnssdCounters &aDnssdCounters); @@ -240,6 +244,16 @@ template <> struct DBusTypeTrait<SrpServerInfo> static constexpr const char *TYPE_AS_STRING = "(yqy(uutttt)(uutttt)(uuuuuu))"; }; +template <> struct DBusTypeTrait<MdnsTelemetryInfo> +{ + // struct of { struct of { uint32, uint32, uint32, uint32, uint32, uint32 }, + // struct of { uint32, uint32, uint32, uint32, uint32, uint32 }, + // struct of { uint32, uint32, uint32, uint32, uint32, uint32 }, + // struct of { uint32, uint32, uint32, uint32, uint32, uint32 }, + // uint32, uint32, uint32, uint32 } + static constexpr const char *TYPE_AS_STRING = "((uuuuuu)(uuuuuu)(uuuuuu)(uuuuuu)uuuu)"; +}; + template <> struct DBusTypeTrait<DnssdCounters> { // struct of { uint32, uint32, uint32, uint32, uint32, uint32, uint32 } diff --git a/src/dbus/common/dbus_message_helper_openthread.cpp b/src/dbus/common/dbus_message_helper_openthread.cpp index 29db6822..68f7c445 100644 --- a/src/dbus/common/dbus_message_helper_openthread.cpp +++ b/src/dbus/common/dbus_message_helper_openthread.cpp @@ -651,5 +651,87 @@ exit: return error; } +otbrError DBusMessageEncode(DBusMessageIter *aIter, const MdnsResponseCounters &aMdnsResponseCounters) +{ + DBusMessageIter sub; + otbrError error = OTBR_ERROR_NONE; + + VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS); + + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsResponseCounters.mSuccess)); + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsResponseCounters.mNotFound)); + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsResponseCounters.mInvalidArgs)); + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsResponseCounters.mDuplicated)); + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsResponseCounters.mNotImplemented)); + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsResponseCounters.mUnknownError)); + + VerifyOrExit(dbus_message_iter_close_container(aIter, &sub), error = OTBR_ERROR_DBUS); +exit: + return error; +} + +otbrError DBusMessageExtract(DBusMessageIter *aIter, MdnsResponseCounters &aMdnsResponseCounters) +{ + DBusMessageIter sub; + otbrError error = OTBR_ERROR_NONE; + + dbus_message_iter_recurse(aIter, &sub); + + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsResponseCounters.mSuccess)); + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsResponseCounters.mNotFound)); + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsResponseCounters.mInvalidArgs)); + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsResponseCounters.mDuplicated)); + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsResponseCounters.mNotImplemented)); + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsResponseCounters.mUnknownError)); + + dbus_message_iter_next(aIter); +exit: + return error; +} + +otbrError DBusMessageEncode(DBusMessageIter *aIter, const MdnsTelemetryInfo &aMdnsTelemetryInfo) +{ + DBusMessageIter sub; + otbrError error = OTBR_ERROR_NONE; + + VerifyOrExit(dbus_message_iter_open_container(aIter, DBUS_TYPE_STRUCT, nullptr, &sub), error = OTBR_ERROR_DBUS); + + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsTelemetryInfo.mHostRegistrations)); + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsTelemetryInfo.mServiceRegistrations)); + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsTelemetryInfo.mHostResolutions)); + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsTelemetryInfo.mServiceResolutions)); + + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsTelemetryInfo.mHostRegistrationEmaLatency)); + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsTelemetryInfo.mServiceRegistrationEmaLatency)); + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsTelemetryInfo.mHostResolutionEmaLatency)); + SuccessOrExit(error = DBusMessageEncode(&sub, aMdnsTelemetryInfo.mServiceResolutionEmaLatency)); + + VerifyOrExit(dbus_message_iter_close_container(aIter, &sub), error = OTBR_ERROR_DBUS); +exit: + return error; +} + +otbrError DBusMessageExtract(DBusMessageIter *aIter, MdnsTelemetryInfo &aMdnsTelemetryInfo) +{ + DBusMessageIter sub; + otbrError error = OTBR_ERROR_NONE; + + dbus_message_iter_recurse(aIter, &sub); + + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsTelemetryInfo.mHostRegistrations)); + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsTelemetryInfo.mServiceRegistrations)); + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsTelemetryInfo.mHostResolutions)); + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsTelemetryInfo.mServiceResolutions)); + + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsTelemetryInfo.mHostRegistrationEmaLatency)); + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsTelemetryInfo.mServiceRegistrationEmaLatency)); + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsTelemetryInfo.mHostResolutionEmaLatency)); + SuccessOrExit(error = DBusMessageExtract(&sub, aMdnsTelemetryInfo.mServiceResolutionEmaLatency)); + + dbus_message_iter_next(aIter); +exit: + return error; +} + } // namespace DBus } // namespace otbr diff --git a/src/dbus/server/dbus_agent.cpp b/src/dbus/server/dbus_agent.cpp index 905f3a30..de94927d 100644 --- a/src/dbus/server/dbus_agent.cpp +++ b/src/dbus/server/dbus_agent.cpp @@ -36,6 +36,7 @@ #include "common/logging.hpp" #include "dbus/common/constants.hpp" +#include "mdns/mdns.hpp" namespace otbr { namespace DBus { @@ -43,9 +44,10 @@ namespace DBus { const struct timeval DBusAgent::kPollTimeout = {0, 0}; constexpr std::chrono::seconds DBusAgent::kDBusWaitAllowance; -DBusAgent::DBusAgent(otbr::Ncp::ControllerOpenThread &aNcp) +DBusAgent::DBusAgent(otbr::Ncp::ControllerOpenThread &aNcp, Mdns::Publisher &aPublisher) : mInterfaceName(aNcp.GetInterfaceName()) , mNcp(aNcp) + , mPublisher(aPublisher) { } @@ -63,8 +65,9 @@ void DBusAgent::Init(void) VerifyOrDie(mConnection != nullptr, "Failed to get DBus connection"); - mThreadObject = std::unique_ptr<DBusThreadObject>(new DBusThreadObject(mConnection.get(), mInterfaceName, &mNcp)); - error = mThreadObject->Init(); + mThreadObject = + std::unique_ptr<DBusThreadObject>(new DBusThreadObject(mConnection.get(), mInterfaceName, &mNcp, &mPublisher)); + error = mThreadObject->Init(); VerifyOrDie(error == OTBR_ERROR_NONE, "Failed to initialize DBus Agent"); } diff --git a/src/dbus/server/dbus_agent.hpp b/src/dbus/server/dbus_agent.hpp index ae5ed126..d334a965 100644 --- a/src/dbus/server/dbus_agent.hpp +++ b/src/dbus/server/dbus_agent.hpp @@ -60,7 +60,7 @@ public: * @param[in] aNcp A reference to the NCP controller. * */ - DBusAgent(otbr::Ncp::ControllerOpenThread &aNcp); + DBusAgent(otbr::Ncp::ControllerOpenThread &aNcp, Mdns::Publisher &aPublisher); /** * This method initializes the dbus agent. @@ -87,6 +87,7 @@ private: std::unique_ptr<DBusThreadObject> mThreadObject; UniqueDBusConnection mConnection; otbr::Ncp::ControllerOpenThread & mNcp; + Mdns::Publisher & mPublisher; /** * This map is used to track DBusWatch-es. diff --git a/src/dbus/server/dbus_thread_object.cpp b/src/dbus/server/dbus_thread_object.cpp index 51727e7e..df7b76f5 100644 --- a/src/dbus/server/dbus_thread_object.cpp +++ b/src/dbus/server/dbus_thread_object.cpp @@ -95,9 +95,11 @@ namespace DBus { DBusThreadObject::DBusThreadObject(DBusConnection * aConnection, const std::string & aInterfaceName, - otbr::Ncp::ControllerOpenThread *aNcp) + otbr::Ncp::ControllerOpenThread *aNcp, + Mdns::Publisher * aPublisher) : DBusObject(aConnection, OTBR_DBUS_OBJECT_PREFIX + aInterfaceName) , mNcp(aNcp) + , mPublisher(aPublisher) { } @@ -222,6 +224,8 @@ otbrError DBusThreadObject::Init(void) std::bind(&DBusThreadObject::GetRadioRegionHandler, this, _1)); RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_SRP_SERVER_INFO, std::bind(&DBusThreadObject::GetSrpServerInfoHandler, this, _1)); + RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_MDNS_TELEMETRY_INFO, + std::bind(&DBusThreadObject::GetMdnsTelemetryInfoHandler, this, _1)); RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_DNSSD_COUNTERS, std::bind(&DBusThreadObject::GetDnssdCountersHandler, this, _1)); RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_OT_HOST_VERSION, @@ -1273,6 +1277,16 @@ exit: #endif // OTBR_ENABLE_SRP_ADVERTISING_PROXY } +otError DBusThreadObject::GetMdnsTelemetryInfoHandler(DBusMessageIter &aIter) +{ + otError error = OT_ERROR_NONE; + + VerifyOrExit(DBusMessageEncodeToVariant(&aIter, mPublisher->GetMdnsTelemetryInfo()) == OTBR_ERROR_NONE, + error = OT_ERROR_INVALID_ARGS); +exit: + return error; +} + otError DBusThreadObject::GetDnssdCountersHandler(DBusMessageIter &aIter) { #if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY diff --git a/src/dbus/server/dbus_thread_object.hpp b/src/dbus/server/dbus_thread_object.hpp index daad87b4..e11c05bf 100644 --- a/src/dbus/server/dbus_thread_object.hpp +++ b/src/dbus/server/dbus_thread_object.hpp @@ -39,6 +39,7 @@ #include <openthread/link.h> #include "dbus/server/dbus_object.hpp" +#include "mdns/mdns.hpp" #include "ncp/ncp_openthread.hpp" namespace otbr { @@ -66,11 +67,13 @@ public: * @param[in] aConnection The dbus connection. * @param[in] aInterfaceName The dbus interface name. * @param[in] aNcp The ncp controller + * @param[in] aPublisher The Mdns::Publisher * */ DBusThreadObject(DBusConnection * aConnection, const std::string & aInterfaceName, - otbr::Ncp::ControllerOpenThread *aNcp); + otbr::Ncp::ControllerOpenThread *aNcp, + Mdns::Publisher * aPublisher); otbrError Init(void) override; @@ -140,6 +143,7 @@ private: otError GetActiveDatasetTlvsHandler(DBusMessageIter &aIter); otError GetRadioRegionHandler(DBusMessageIter &aIter); otError GetSrpServerInfoHandler(DBusMessageIter &aIter); + otError GetMdnsTelemetryInfoHandler(DBusMessageIter &aIter); otError GetDnssdCountersHandler(DBusMessageIter &aIter); otError GetOtHostVersionHandler(DBusMessageIter &aIter); otError GetOtRcpVersionHandler(DBusMessageIter &aIter); @@ -150,6 +154,7 @@ private: otbr::Ncp::ControllerOpenThread * mNcp; std::unordered_map<std::string, PropertyHandlerType> mGetPropertyHandlers; + otbr::Mdns::Publisher * mPublisher; }; } // namespace DBus diff --git a/src/dbus/server/introspect.xml b/src/dbus/server/introspect.xml index 8a28f2de..b644804f 100644 --- a/src/dbus/server/introspect.xml +++ b/src/dbus/server/introspect.xml @@ -578,6 +578,52 @@ <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> </property> + <!-- MdnsTelemetryInfo: The MDNS information + <literallayout> + struct { + struct { // host registration responses + uint32 success + uint32 not_found + uint32 invalid_args + uint32 duplicated + uint32 not_implemented + uint32 unknown_error + } + struct { // service registration responses + uint32 success + uint32 not_found + uint32 invalid_args + uint32 duplicated + uint32 not_implemented + uint32 unknown_error + } + struct { // host resolution responses + uint32 success + uint32 not_found + uint32 invalid_args + uint32 duplicated + uint32 not_implemented + uint32 unknown_error + } + struct { // service resolution responses + uint32 success + uint32 not_found + uint32 invalid_args + uint32 duplicated + uint32 not_implemented + uint32 unknown_error + } + uint32 host_registration_ema_latency + uint32 service_registration_ema_latency + uint32 host_resolution_ema_latency + uint32 service_resolution_ema_latency + } + </literallayout> + --> + <property name="MdnsTelemetryInfo" type="(uuuuuu)(uuuuuu)(uuuuuu)(uuuuuu)uuuu" access="read"> + <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> + </property> + <!-- OtHostVersion: The version string of the host build. --> <property name="OtHostVersion" type="s" access="read"> <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/> diff --git a/src/mdns/mdns.cpp b/src/mdns/mdns.cpp index 8b9a92d5..ff59f4a8 100644 --- a/src/mdns/mdns.cpp +++ b/src/mdns/mdns.cpp @@ -47,6 +47,40 @@ namespace otbr { namespace Mdns { +void Publisher::PublishService(const std::string &aHostName, + const std::string &aName, + const std::string &aType, + const SubTypeList &aSubTypeList, + uint16_t aPort, + const TxtList & aTxtList, + ResultCallback && aCallback) +{ + mServiceRegistrationBeginTime[std::make_pair(aName, aType)] = Clock::now(); + + PublishServiceImpl(aHostName, aName, aType, aSubTypeList, aPort, aTxtList, std::move(aCallback)); +} + +void Publisher::PublishHost(const std::string &aName, const std::vector<uint8_t> &aAddress, ResultCallback &&aCallback) +{ + mHostRegistrationBeginTime[aName] = Clock::now(); + + PublishHostImpl(aName, aAddress, std::move(aCallback)); +} + +void Publisher::OnServiceResolveFailed(const std::string &aType, const std::string &aInstanceName, int32_t aErrorCode) +{ + UpdateMdnsResponseCounters(mTelemetryInfo.mServiceResolutions, DnsErrorToOtbrError(aErrorCode)); + UpdateServiceInstanceResolutionEmaLatency(aInstanceName, aType, DnsErrorToOtbrError(aErrorCode)); + OnServiceResolveFailedImpl(aType, aInstanceName, aErrorCode); +} + +void Publisher::OnHostResolveFailed(const std::string &aHostName, int32_t aErrorCode) +{ + UpdateMdnsResponseCounters(mTelemetryInfo.mHostResolutions, DnsErrorToOtbrError(aErrorCode)); + UpdateHostResolutionEmaLatency(aHostName, DnsErrorToOtbrError(aErrorCode)); + OnHostResolveFailedImpl(aHostName, aErrorCode); +} + otbrError Publisher::EncodeTxtData(const TxtList &aTxtList, std::vector<uint8_t> &aTxtData) { otbrError error = OTBR_ERROR_NONE; @@ -142,6 +176,9 @@ void Publisher::OnServiceResolved(const std::string &aType, const DiscoveredInst DnsUtils::CheckHostnameSanity(aInstanceInfo.mHostName); } + UpdateMdnsResponseCounters(mTelemetryInfo.mServiceResolutions, OTBR_ERROR_NONE); + UpdateServiceInstanceResolutionEmaLatency(aInstanceInfo.mName, aType, OTBR_ERROR_NONE); + for (const auto &subCallback : mDiscoveredCallbacks) { if (subCallback.second.first != nullptr) @@ -174,6 +211,9 @@ void Publisher::OnHostResolved(const std::string &aHostName, const Publisher::Di DnsUtils::CheckHostnameSanity(aHostInfo.mHostName); } + UpdateMdnsResponseCounters(mTelemetryInfo.mHostResolutions, OTBR_ERROR_NONE); + UpdateHostResolutionEmaLatency(aHostName, OTBR_ERROR_NONE); + for (const auto &subCallback : mDiscoveredCallbacks) { if (subCallback.second.second != nullptr) @@ -348,7 +388,7 @@ Publisher::HostRegistration *Publisher::FindHostRegistration(const std::string & Publisher::Registration::~Registration(void) { - Complete(OTBR_ERROR_ABORTED); + TriggerCompleteCallback(OTBR_ERROR_ABORTED); } bool Publisher::ServiceRegistration::IsOutdated(const std::string &aHostName, @@ -362,11 +402,139 @@ bool Publisher::ServiceRegistration::IsOutdated(const std::string &aHostName, mPort == aPort && mTxtList == aTxtList); } +void Publisher::ServiceRegistration::Complete(otbrError aError) +{ + OnComplete(aError); + Registration::TriggerCompleteCallback(aError); +} + +void Publisher::ServiceRegistration::OnComplete(otbrError aError) +{ + if (!IsCompleted()) + { + mPublisher->UpdateMdnsResponseCounters(mPublisher->mTelemetryInfo.mServiceRegistrations, aError); + mPublisher->UpdateServiceRegistrationEmaLatency(mName, mType, aError); + } +} + bool Publisher::HostRegistration::IsOutdated(const std::string &aName, const std::vector<uint8_t> &aAddress) const { return !(mName == aName && mAddress == aAddress); } +void Publisher::HostRegistration::Complete(otbrError aError) +{ + OnComplete(aError); + Registration::TriggerCompleteCallback(aError); +} + +void Publisher::HostRegistration::OnComplete(otbrError aError) +{ + if (!IsCompleted()) + { + mPublisher->UpdateMdnsResponseCounters(mPublisher->mTelemetryInfo.mHostRegistrations, aError); + mPublisher->UpdateHostRegistrationEmaLatency(mName, aError); + } +} + +void Publisher::UpdateMdnsResponseCounters(otbr::MdnsResponseCounters &aCounters, otbrError aError) +{ + switch (aError) + { + case OTBR_ERROR_NONE: + ++aCounters.mSuccess; + break; + case OTBR_ERROR_NOT_FOUND: + ++aCounters.mNotFound; + break; + case OTBR_ERROR_INVALID_ARGS: + ++aCounters.mInvalidArgs; + break; + case OTBR_ERROR_DUPLICATED: + ++aCounters.mDuplicated; + break; + case OTBR_ERROR_NOT_IMPLEMENTED: + ++aCounters.mNotImplemented; + break; + case OTBR_ERROR_MDNS: + default: + ++aCounters.mUnknownError; + break; + } +} + +void Publisher::UpdateEmaLatency(uint32_t &aEmaLatency, uint32_t aLatency, otbrError aError) +{ + VerifyOrExit(aError != OTBR_ERROR_ABORTED); + + if (!aEmaLatency) + { + aEmaLatency = aLatency; + } + else + { + aEmaLatency = + (aLatency * MdnsTelemetryInfo::kEmaFactorNumerator + + aEmaLatency * (MdnsTelemetryInfo::kEmaFactorDenominator - MdnsTelemetryInfo::kEmaFactorNumerator)) / + MdnsTelemetryInfo::kEmaFactorDenominator; + } + +exit: + return; +} + +void Publisher::UpdateServiceRegistrationEmaLatency(const std::string &aInstanceName, + const std::string &aType, + otbrError aError) +{ + auto it = mServiceRegistrationBeginTime.find(std::make_pair(aInstanceName, aType)); + + if (it != mServiceRegistrationBeginTime.end()) + { + uint32_t latency = std::chrono::duration_cast<Milliseconds>(Clock::now() - it->second).count(); + UpdateEmaLatency(mTelemetryInfo.mServiceRegistrationEmaLatency, latency, aError); + mServiceRegistrationBeginTime.erase(it); + } +} + +void Publisher::UpdateHostRegistrationEmaLatency(const std::string &aHostName, otbrError aError) +{ + auto it = mHostRegistrationBeginTime.find(aHostName); + + if (it != mHostRegistrationBeginTime.end()) + { + uint32_t latency = std::chrono::duration_cast<Milliseconds>(Clock::now() - it->second).count(); + UpdateEmaLatency(mTelemetryInfo.mHostRegistrationEmaLatency, latency, aError); + mHostRegistrationBeginTime.erase(it); + } +} + +void Publisher::UpdateServiceInstanceResolutionEmaLatency(const std::string &aInstanceName, + const std::string &aType, + otbrError aError) +{ + auto it = mServiceInstanceResolutionBeginTime.find(std::make_pair(aInstanceName, aType)); + + if (it != mServiceInstanceResolutionBeginTime.end()) + { + uint32_t latency = std::chrono::duration_cast<Milliseconds>(Clock::now() - it->second).count(); + UpdateEmaLatency(mTelemetryInfo.mServiceResolutionEmaLatency, latency, aError); + mServiceInstanceResolutionBeginTime.erase(it); + } +} + +void Publisher::UpdateHostResolutionEmaLatency(const std::string &aHostName, otbrError aError) +{ + auto it = mHostResolutionBeginTime.find(aHostName); + + if (it != mHostResolutionBeginTime.end()) + { + uint32_t latency = std::chrono::duration_cast<Milliseconds>(Clock::now() - it->second).count(); + UpdateEmaLatency(mTelemetryInfo.mHostResolutionEmaLatency, latency, aError); + mHostResolutionBeginTime.erase(it); + } +} + } // namespace Mdns } // namespace otbr diff --git a/src/mdns/mdns.hpp b/src/mdns/mdns.hpp index bd203990..8307584c 100644 --- a/src/mdns/mdns.hpp +++ b/src/mdns/mdns.hpp @@ -44,6 +44,7 @@ #include "common/callback.hpp" #include "common/code_utils.hpp" +#include "common/time.hpp" #include "common/types.hpp" namespace otbr { @@ -199,13 +200,13 @@ public: * alternative name is available/acceptable. * */ - virtual void PublishService(const std::string &aHostName, - const std::string &aName, - const std::string &aType, - const SubTypeList &aSubTypeList, - uint16_t aPort, - const TxtList & aTxtList, - ResultCallback && aCallback) = 0; + void PublishService(const std::string &aHostName, + const std::string &aName, + const std::string &aType, + const SubTypeList &aSubTypeList, + uint16_t aPort, + const TxtList & aTxtList, + ResultCallback && aCallback); /** * This method un-publishes a service. @@ -232,9 +233,7 @@ public: * alternative name is available/acceptable. * */ - virtual void PublishHost(const std::string & aName, - const std::vector<uint8_t> &aAddress, - ResultCallback && aCallback) = 0; + void PublishHost(const std::string &aName, const std::vector<uint8_t> &aAddress, ResultCallback &&aCallback); /** * This method un-publishes a host. @@ -317,6 +316,14 @@ public: */ void RemoveSubscriptionCallbacks(uint64_t aSubscriberId); + /** + * This method returns the mDNS statistics information of the publisher. + * + * @returns The MdnsTelemetryInfo of the publisher. + * + */ + const MdnsTelemetryInfo &GetMdnsTelemetryInfo() const { return mTelemetryInfo; } + virtual ~Publisher(void) = default; /** @@ -380,25 +387,28 @@ protected: { public: ResultCallback mCallback; + Publisher * mPublisher; - Registration(ResultCallback &&aCallback) + 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 Complete(otbrError aError) + void TriggerCompleteCallback(otbrError aError) { if (!IsCompleted()) { std::move(mCallback)(aError); } } - - // Tells whether the service registration has been completed (typically by calling - // `ServiceRegistration::Complete`). - bool IsCompleted() const { return mCallback.IsNull(); } }; class ServiceRegistration : public Registration @@ -417,8 +427,9 @@ protected: SubTypeList aSubTypeList, uint16_t aPort, TxtList aTxtList, - ResultCallback &&aCallback) - : Registration(std::move(aCallback)) + ResultCallback &&aCallback, + Publisher * aPublisher) + : Registration(std::move(aCallback), aPublisher) , mHostName(std::move(aHostName)) , mName(std::move(aName)) , mType(std::move(aType)) @@ -427,7 +438,11 @@ protected: , mTxtList(SortTxtList(std::move(aTxtList))) { } - ~ServiceRegistration(void) override = default; + ~ServiceRegistration(void) override { OnComplete(OTBR_ERROR_ABORTED); } + + void Complete(otbrError aError); + + void OnComplete(otbrError aError); // Tells whether this `ServiceRegistration` object is outdated comparing to the given parameters. bool IsOutdated(const std::string &aHostName, @@ -444,14 +459,21 @@ protected: std::string mName; std::vector<uint8_t> mAddress; - HostRegistration(std::string aName, std::vector<uint8_t> aAddress, ResultCallback &&aCallback) - : Registration(std::move(aCallback)) + HostRegistration(std::string aName, + std::vector<uint8_t> aAddress, + ResultCallback && aCallback, + Publisher * aPublisher) + : Registration(std::move(aCallback), aPublisher) , mName(std::move(aName)) , mAddress(std::move(aAddress)) { } - ~HostRegistration(void) override = default; + ~HostRegistration(void) { OnComplete(OTBR_ERROR_ABORTED); } + + void Complete(otbrError aError); + + void OnComplete(otbrError); // Tells whether this `HostRegistration` object is outdated comparing to the given parameters. bool IsOutdated(const std::string &aName, const std::vector<uint8_t> &aAddress) const; @@ -467,12 +489,31 @@ protected: static std::string MakeFullServiceName(const std::string &aName, const std::string &aType); static std::string MakeFullHostName(const std::string &aName); + virtual void PublishServiceImpl(const std::string &aHostName, + const std::string &aName, + const std::string &aType, + const SubTypeList &aSubTypeList, + uint16_t aPort, + const TxtList & aTxtList, + ResultCallback && aCallback) = 0; + virtual void PublishHostImpl(const std::string & aName, + const std::vector<uint8_t> &aAddress, + 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); void OnServiceResolved(const std::string &aType, const DiscoveredInstanceInfo &aInstanceInfo); + void OnServiceResolveFailed(const std::string &aType, const std::string &aInstanceName, int32_t aErrorCode); void OnServiceRemoved(uint32_t aNetifIndex, const std::string &aType, const std::string &aInstanceName); void OnHostResolved(const std::string &aHostName, const DiscoveredHostInfo &aHostInfo); + void OnHostResolveFailed(const 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 @@ -493,12 +534,34 @@ protected: void RemoveHostRegistration(const std::string &aName, otbrError aError); HostRegistration *FindHostRegistration(const std::string &aName); + static void UpdateMdnsResponseCounters(otbr::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 UpdateServiceInstanceResolutionEmaLatency(const std::string &aInstanceName, + const std::string &aType, + otbrError aError); + void UpdateHostResolutionEmaLatency(const std::string &aHostName, otbrError aError); + ServiceRegistrationMap mServiceRegistrations; HostRegistrationMap mHostRegistrations; uint64_t mNextSubscriberId = 1; std::map<uint64_t, std::pair<DiscoveredServiceInstanceCallback, DiscoveredHostCallback>> mDiscoveredCallbacks; + // {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; + // {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; + + otbr::MdnsTelemetryInfo mTelemetryInfo{}; }; /** diff --git a/src/mdns/mdns_avahi.cpp b/src/mdns/mdns_avahi.cpp index 336d4dfa..483a8d73 100644 --- a/src/mdns/mdns_avahi.cpp +++ b/src/mdns/mdns_avahi.cpp @@ -122,6 +122,42 @@ namespace otbr { namespace Mdns { +static otbrError DnsErrorToOtbrError(int aAvahiError) +{ + otbrError error; + + switch (aAvahiError) + { + case AVAHI_OK: + case AVAHI_ERR_INVALID_ADDRESS: + error = OTBR_ERROR_NONE; + break; + + case AVAHI_ERR_NOT_FOUND: + error = OTBR_ERROR_NOT_FOUND; + break; + + case AVAHI_ERR_INVALID_ARGUMENT: + error = OTBR_ERROR_INVALID_ARGS; + break; + + case AVAHI_ERR_COLLISION: + error = OTBR_ERROR_DUPLICATED; + break; + + case AVAHI_ERR_DNS_NOTIMP: + case AVAHI_ERR_NOT_SUPPORTED: + error = OTBR_ERROR_NOT_IMPLEMENTED; + break; + + default: + error = OTBR_ERROR_MDNS; + break; + } + + return error; +} + class AvahiPoller : public MainloopProcessor { public: @@ -598,13 +634,13 @@ void PublisherAvahi::HandleClientState(AvahiClient *aClient, AvahiClientState aS } } -void PublisherAvahi::PublishService(const std::string &aHostName, - const std::string &aName, - const std::string &aType, - const SubTypeList &aSubTypeList, - uint16_t aPort, - const TxtList & aTxtList, - ResultCallback && aCallback) +void PublisherAvahi::PublishServiceImpl(const std::string &aHostName, + const std::string &aName, + const std::string &aType, + const SubTypeList &aSubTypeList, + uint16_t aPort, + const TxtList & aTxtList, + ResultCallback && aCallback) { otbrError error = OTBR_ERROR_NONE; int avahiError = AVAHI_OK; @@ -652,7 +688,7 @@ void PublisherAvahi::PublishService(const std::string &aHostName, VerifyOrExit(avahiError == AVAHI_OK); AddServiceRegistration(std::unique_ptr<AvahiServiceRegistration>(new AvahiServiceRegistration( - aHostName, aName, aType, sortedSubTypeList, aPort, sortedTxtList, std::move(aCallback), group))); + aHostName, aName, aType, sortedSubTypeList, aPort, sortedTxtList, std::move(aCallback), group, this))); exit: if (avahiError != AVAHI_OK || error != OTBR_ERROR_NONE) @@ -682,9 +718,9 @@ exit: std::move(aCallback)(error); } -void PublisherAvahi::PublishHost(const std::string & aName, - const std::vector<uint8_t> &aAddress, - ResultCallback && aCallback) +void PublisherAvahi::PublishHostImpl(const std::string & aName, + const std::vector<uint8_t> &aAddress, + ResultCallback && aCallback) { otbrError error = OTBR_ERROR_NONE; int avahiError = AVAHI_OK; @@ -713,7 +749,7 @@ void PublisherAvahi::PublishHost(const std::string & aName, VerifyOrExit(avahiError == AVAHI_OK); AddHostRegistration(std::unique_ptr<AvahiHostRegistration>( - new AvahiHostRegistration(aName, aAddress, std::move(aCallback), group))); + new AvahiHostRegistration(aName, aAddress, std::move(aCallback), group, this))); exit: if (avahiError != AVAHI_OK || error != OTBR_ERROR_NONE) @@ -865,14 +901,22 @@ exit: return; } -void PublisherAvahi::OnServiceResolveFailed(const ServiceSubscription &aService, int aErrorCode) +void PublisherAvahi::OnServiceResolveFailedImpl(const std::string &aType, + const std::string &aInstanceName, + int32_t aErrorCode) +{ + otbrLogWarning("Resolve service %s.%s failed: %s", aInstanceName.c_str(), aType.c_str(), + avahi_strerror(aErrorCode)); +} + +void PublisherAvahi::OnHostResolveFailedImpl(const std::string &aHostName, int32_t aErrorCode) { - otbrLogWarning("Resolve service %s failed: %s", aService.mType.c_str(), avahi_strerror(aErrorCode)); + otbrLogWarning("Resolve host %s failed: %s", aHostName.c_str(), avahi_strerror(aErrorCode)); } -void PublisherAvahi::OnHostResolveFailed(const HostSubscription &aHost, int aErrorCode) +otbrError PublisherAvahi::DnsErrorToOtbrError(int32_t aErrorCode) { - otbrLogWarning("Resolve host %s failed: %s", aHost.mHostName.c_str(), avahi_strerror(aErrorCode)); + return otbr::Mdns::DnsErrorToOtbrError(aErrorCode); } void PublisherAvahi::SubscribeHost(const std::string &aHostName) @@ -1001,7 +1045,7 @@ void PublisherAvahi::ServiceSubscription::HandleBrowseResult(AvahiServiceBrowser // do nothing break; case AVAHI_BROWSER_FAILURE: - mPublisherAvahi->OnServiceResolveFailed(*this, avahi_client_errno(mPublisherAvahi->mClient)); + mPublisherAvahi->OnServiceResolveFailed(aType, aName, avahi_client_errno(mPublisherAvahi->mClient)); break; } } @@ -1013,6 +1057,8 @@ void PublisherAvahi::ServiceSubscription::Resolve(uint32_t aInterfaceI { AvahiServiceResolver *resolver; + mPublisherAvahi->mServiceInstanceResolutionBeginTime[std::make_pair(aInstanceName, aType)] = Clock::now(); + otbrLogInfo("Resolve service %s.%s inf %" PRIu32, aInstanceName.c_str(), aType.c_str(), aInterfaceIndex); resolver = avahi_service_resolver_new( @@ -1123,7 +1169,7 @@ exit: } else if (avahiError != AVAHI_OK) { - mPublisherAvahi->OnServiceResolveFailed(*this, avahi_client_errno(mPublisherAvahi->mClient)); + mPublisherAvahi->OnServiceResolveFailed(aType, aName, avahiError); } } @@ -1155,6 +1201,8 @@ void PublisherAvahi::HostSubscription::Resolve(void) { std::string fullHostName = MakeFullHostName(mHostName); + mPublisherAvahi->mHostResolutionBeginTime[mHostName] = Clock::now(); + otbrLogInfo("Resolve host %s inf %d", fullHostName.c_str(), static_cast<int>(AVAHI_IF_UNSPEC)); mRecordBrowser = avahi_record_browser_new(mPublisherAvahi->mClient, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, fullHostName.c_str(), AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA, @@ -1235,7 +1283,7 @@ exit: } else if (avahiError != AVAHI_OK) { - mPublisherAvahi->OnHostResolveFailed(*this, avahiError); + mPublisherAvahi->OnHostResolveFailed(mHostName, avahiError); } } diff --git a/src/mdns/mdns_avahi.hpp b/src/mdns/mdns_avahi.hpp index daee1ca6..efd7e940 100644 --- a/src/mdns/mdns_avahi.hpp +++ b/src/mdns/mdns_avahi.hpp @@ -74,17 +74,7 @@ public: PublisherAvahi(StateCallback aStateCallback); ~PublisherAvahi(void) override; - void PublishService(const std::string &aHostName, - const std::string &aName, - const std::string &aType, - const SubTypeList &aSubTypeList, - uint16_t aPort, - const TxtList & aTxtList, - ResultCallback && aCallback) override; void UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) override; - void PublishHost(const std::string & aName, - const std::vector<uint8_t> &aAddress, - ResultCallback && aCallback) override; void UnpublishHost(const std::string &aName, ResultCallback &&aCallback) override; void SubscribeService(const std::string &aType, const std::string &aInstanceName) override; void UnsubscribeService(const std::string &aType, const std::string &aInstanceName) override; @@ -94,6 +84,23 @@ public: bool IsStarted(void) const override; void Stop(void) override; +protected: + void PublishServiceImpl(const std::string &aHostName, + const std::string &aName, + const std::string &aType, + const SubTypeList &aSubTypeList, + uint16_t aPort, + const TxtList & aTxtList, + ResultCallback && aCallback) override; + void PublishHostImpl(const std::string & aName, + const std::vector<uint8_t> &aAddress, + ResultCallback && aCallback) override; + void OnServiceResolveFailedImpl(const std::string &aType, + const std::string &aInstanceName, + int32_t aErrorCode) override; + void OnHostResolveFailedImpl(const std::string &aHostName, int32_t aErrorCode) override; + otbrError DnsErrorToOtbrError(int32_t aErrorCode) override; + private: static constexpr size_t kMaxSizeOfTxtRecord = 1024; static constexpr uint32_t kDefaultTtl = 10; // In seconds. @@ -108,8 +115,16 @@ private: uint16_t aPort, const TxtList & aTxtList, ResultCallback && aCallback, - AvahiEntryGroup * aEntryGroup) - : ServiceRegistration(aHostName, aName, aType, aSubTypeList, aPort, aTxtList, std::move(aCallback)) + AvahiEntryGroup * aEntryGroup, + PublisherAvahi * aPublisher) + : ServiceRegistration(aHostName, + aName, + aType, + aSubTypeList, + aPort, + aTxtList, + std::move(aCallback), + aPublisher) , mEntryGroup(aEntryGroup) { } @@ -127,8 +142,9 @@ private: AvahiHostRegistration(const std::string & aName, const std::vector<uint8_t> &aAddress, ResultCallback && aCallback, - AvahiEntryGroup * aEntryGroup) - : HostRegistration(aName, aAddress, std::move(aCallback)) + AvahiEntryGroup * aEntryGroup, + PublisherAvahi * aPublisher) + : HostRegistration(aName, aAddress, std::move(aCallback), aPublisher) , mEntryGroup(aEntryGroup) { } @@ -285,9 +301,6 @@ private: ServiceRegistration *FindServiceRegistration(const AvahiEntryGroup *aEntryGroup); HostRegistration * FindHostRegistration(const AvahiEntryGroup *aEntryGroup); - static void OnServiceResolveFailed(const ServiceSubscription &aService, int aErrorCode); - void OnHostResolveFailed(const HostSubscription &aHost, int aErrorCode); - AvahiClient * mClient; std::unique_ptr<AvahiPoller> mPoller; State mState; diff --git a/src/mdns/mdns_mdnssd.cpp b/src/mdns/mdns_mdnssd.cpp index 25931694..e091323d 100644 --- a/src/mdns/mdns_mdnssd.cpp +++ b/src/mdns/mdns_mdnssd.cpp @@ -450,6 +450,7 @@ void PublisherMDnsSd::HandleServiceRegisterResult(DNSServiceRef aService { OTBR_UNUSED_VARIABLE(aDomain); + otbrError error = DNSErrorToOtbrError(aError); std::string originalInstanceName; ServiceRegistration *serviceReg = FindServiceRegistration(aServiceRef); @@ -465,20 +466,20 @@ void PublisherMDnsSd::HandleServiceRegisterResult(DNSServiceRef aService else { otbrLogErr("Failed to register service %s.%s: %s", aName, aType, DNSErrorToString(aError)); - RemoveServiceRegistration(serviceReg->mName, serviceReg->mType, DNSErrorToOtbrError(aError)); + RemoveServiceRegistration(serviceReg->mName, serviceReg->mType, error); } exit: return; } -void PublisherMDnsSd::PublishService(const std::string &aHostName, - const std::string &aName, - const std::string &aType, - const SubTypeList &aSubTypeList, - uint16_t aPort, - const TxtList & aTxtList, - ResultCallback && aCallback) +void PublisherMDnsSd::PublishServiceImpl(const std::string &aHostName, + const std::string &aName, + const std::string &aType, + const SubTypeList &aSubTypeList, + uint16_t aPort, + const TxtList & aTxtList, + ResultCallback && aCallback) { otbrError ret = OTBR_ERROR_NONE; int error = 0; @@ -507,7 +508,7 @@ void PublisherMDnsSd::PublishService(const std::string &aHostName, !aHostName.empty() ? fullHostName.c_str() : nullptr, htons(aPort), txt.size(), txt.data(), HandleServiceRegisterResult, this)); AddServiceRegistration(std::unique_ptr<DnssdServiceRegistration>(new DnssdServiceRegistration( - aHostName, aName, aType, sortedSubTypeList, aPort, sortedTxtList, std::move(aCallback), serviceRef))); + aHostName, aName, aType, sortedSubTypeList, aPort, sortedTxtList, std::move(aCallback), serviceRef, this))); exit: if (error != kDNSServiceErr_NoError || ret != OTBR_ERROR_NONE) @@ -538,9 +539,9 @@ exit: std::move(aCallback)(error); } -void PublisherMDnsSd::PublishHost(const std::string & aName, - const std::vector<uint8_t> &aAddress, - ResultCallback && aCallback) +void PublisherMDnsSd::PublishHostImpl(const std::string & aName, + const std::vector<uint8_t> &aAddress, + ResultCallback && aCallback) { otbrError ret = OTBR_ERROR_NONE; int error = 0; @@ -569,7 +570,7 @@ void PublisherMDnsSd::PublishHost(const std::string & aName, kDNSServiceClass_IN, aAddress.size(), aAddress.data(), /* ttl */ 0, HandleRegisterHostResult, this)); AddHostRegistration(std::unique_ptr<DnssdHostRegistration>( - new DnssdHostRegistration(aName, aAddress, std::move(aCallback), mHostsRef, recordRef))); + new DnssdHostRegistration(aName, aAddress, std::move(aCallback), mHostsRef, recordRef, this))); exit: if (error != kDNSServiceErr_NoError || ret != OTBR_ERROR_NONE) @@ -697,17 +698,21 @@ exit: return; } -void PublisherMDnsSd::OnServiceResolveFailed(const std::string & aType, - const std::string & aInstanceName, - DNSServiceErrorType aErrorCode) +void PublisherMDnsSd::OnServiceResolveFailedImpl(const std::string &aType, + const std::string &aInstanceName, + int32_t aErrorCode) { otbrLogWarning("Resolve service %s.%s failed: code=%" PRId32, aInstanceName.c_str(), aType.c_str(), aErrorCode); } -void PublisherMDnsSd::OnHostResolveFailed(const PublisherMDnsSd::HostSubscription &aHost, - DNSServiceErrorType aErrorCode) +void PublisherMDnsSd::OnHostResolveFailedImpl(const std::string &aHostName, int32_t aErrorCode) { - otbrLogWarning("Resolve host %s failed: code=%" PRId32, aHost.mHostName.c_str(), aErrorCode); + otbrLogWarning("Resolve host %s failed: code=%" PRId32, aHostName.c_str(), aErrorCode); +} + +otbrError PublisherMDnsSd::DnsErrorToOtbrError(int32_t aErrorCode) +{ + return otbr::Mdns::DNSErrorToOtbrError(aErrorCode); } void PublisherMDnsSd::SubscribeHost(const std::string &aHostName) @@ -901,6 +906,9 @@ void PublisherMDnsSd::ServiceInstanceResolution::Resolve(void) { assert(mServiceRef == nullptr); + mSubscription->mMDnsSd->mServiceInstanceResolutionBeginTime[std::make_pair(mInstanceName, mTypeEndWithDot)] = + Clock::now(); + otbrLogInfo("DNSServiceResolve %s %s inf %u", mInstanceName.c_str(), mTypeEndWithDot.c_str(), mNetifIndex); DNSServiceResolve(&mServiceRef, /* flags */ kDNSServiceFlagsTimeout, mNetifIndex, mInstanceName.c_str(), mTypeEndWithDot.c_str(), mDomain.c_str(), HandleResolveResult, this); @@ -1057,6 +1065,8 @@ void PublisherMDnsSd::HostSubscription::Resolve(void) assert(mServiceRef == nullptr); + mMDnsSd->mHostResolutionBeginTime[mHostName] = Clock::now(); + otbrLogInfo("DNSServiceGetAddrInfo %s inf %d", fullHostName.c_str(), kDNSServiceInterfaceIndexAny); DNSServiceGetAddrInfo(&mServiceRef, /* flags */ 0, kDNSServiceInterfaceIndexAny, @@ -1113,7 +1123,7 @@ void PublisherMDnsSd::HostSubscription::HandleResolveResult(DNSServiceRef exit: if (aErrorCode != kDNSServiceErr_NoError) { - mMDnsSd->OnHostResolveFailed(*this, aErrorCode); + mMDnsSd->OnHostResolveFailed(aHostName, aErrorCode); } } diff --git a/src/mdns/mdns_mdnssd.hpp b/src/mdns/mdns_mdnssd.hpp index 3b9f5cb6..3fff55b6 100644 --- a/src/mdns/mdns_mdnssd.hpp +++ b/src/mdns/mdns_mdnssd.hpp @@ -65,17 +65,8 @@ public: // Implementation of Mdns::Publisher. - void PublishService(const std::string &aHostName, - const std::string &aName, - const std::string &aType, - const SubTypeList &aSubTypeList, - uint16_t aPort, - const TxtList & aTxtList, - ResultCallback && aCallback) override; - void UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) override; - void PublishHost(const std::string & aName, - const std::vector<uint8_t> &aAddress, - ResultCallback && aCallback) override; + void UnpublishService(const std::string &aName, const std::string &aType, ResultCallback &&aCallback) override; + void UnpublishHost(const std::string &aName, ResultCallback &&aCallback) override; void SubscribeService(const std::string &aType, const std::string &aInstanceName) override; void UnsubscribeService(const std::string &aType, const std::string &aInstanceName) override; @@ -90,6 +81,23 @@ public: void Update(MainloopContext &aMainloop) override; void Process(const MainloopContext &aMainloop) override; +protected: + void PublishServiceImpl(const std::string &aHostName, + const std::string &aName, + const std::string &aType, + const SubTypeList &aSubTypeList, + uint16_t aPort, + const TxtList & aTxtList, + ResultCallback && aCallback) override; + void PublishHostImpl(const std::string & aName, + const std::vector<uint8_t> &aAddress, + ResultCallback && aCallback) override; + void OnServiceResolveFailedImpl(const std::string &aType, + const std::string &aInstanceName, + int32_t aErrorCode) override; + void OnHostResolveFailedImpl(const std::string &aHostName, int32_t aErrorCode) override; + otbrError DnsErrorToOtbrError(int32_t aErrorCode) override; + private: static constexpr uint32_t kDefaultTtl = 10; @@ -103,8 +111,16 @@ private: uint16_t aPort, const TxtList & aTxtList, ResultCallback && aCallback, - DNSServiceRef aServiceRef) - : ServiceRegistration(aHostName, aName, aType, aSubTypeList, aPort, aTxtList, std::move(aCallback)) + DNSServiceRef aServiceRef, + PublisherMDnsSd * aPublisher) + : ServiceRegistration(aHostName, + aName, + aType, + aSubTypeList, + aPort, + aTxtList, + std::move(aCallback), + aPublisher) , mServiceRef(aServiceRef) { } @@ -123,8 +139,9 @@ private: const std::vector<uint8_t> &aAddress, ResultCallback && aCallback, DNSServiceRef aServiceRef, - DNSRecordRef aRecordRef) - : HostRegistration(aName, aAddress, std::move(aCallback)) + DNSRecordRef aRecordRef, + Publisher * aPublisher) + : HostRegistration(aName, aAddress, std::move(aCallback), aPublisher) , mServiceRef(aServiceRef) , mRecordRef(aRecordRef) { @@ -325,11 +342,6 @@ private: ServiceRegistration *FindServiceRegistration(const DNSServiceRef &aServiceRef); HostRegistration * FindHostRegistration(const DNSServiceRef &aServiceRef, const DNSRecordRef &aRecordRef); - static void OnServiceResolveFailed(const std::string & aType, - const std::string & aInstanceName, - DNSServiceErrorType aErrorCode); - void OnHostResolveFailed(const HostSubscription &aHost, DNSServiceErrorType aErrorCode); - DNSServiceRef mHostsRef; State mState; StateCallback mStateCallback; |