aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorwhd <7058128+superwhd@users.noreply.github.com>2022-06-28 11:29:00 +0800
committerGitHub <noreply@github.com>2022-06-27 20:29:00 -0700
commite4a197f3397024c3e02bc4dabded434ab865b2af (patch)
tree5ef27b733454e2a739788927552c229266c3a9eb /src
parent489f99934525294fa8b8818ac1f90be188839629 (diff)
downloadot-br-posix-e4a197f3397024c3e02bc4dabded434ab865b2af.tar.gz
[dbus] add D-BUS API `GetMdnsInfo` (#1400)
Diffstat (limited to 'src')
-rw-r--r--src/agent/application.cpp4
-rw-r--r--src/border_agent/border_agent.hpp8
-rw-r--r--src/common/types.hpp30
-rw-r--r--src/dbus/client/thread_api_dbus.cpp5
-rw-r--r--src/dbus/client/thread_api_dbus.hpp12
-rw-r--r--src/dbus/common/constants.hpp1
-rw-r--r--src/dbus/common/dbus_message_helper.hpp14
-rw-r--r--src/dbus/common/dbus_message_helper_openthread.cpp82
-rw-r--r--src/dbus/server/dbus_agent.cpp9
-rw-r--r--src/dbus/server/dbus_agent.hpp3
-rw-r--r--src/dbus/server/dbus_thread_object.cpp16
-rw-r--r--src/dbus/server/dbus_thread_object.hpp7
-rw-r--r--src/dbus/server/introspect.xml46
-rw-r--r--src/mdns/mdns.cpp170
-rw-r--r--src/mdns/mdns.hpp107
-rw-r--r--src/mdns/mdns_avahi.cpp86
-rw-r--r--src/mdns/mdns_avahi.hpp47
-rw-r--r--src/mdns/mdns_mdnssd.cpp50
-rw-r--r--src/mdns/mdns_mdnssd.hpp52
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;