aboutsummaryrefslogtreecommitdiff
path: root/src/agent
diff options
context:
space:
mode:
authorwhd <7058128+superwhd@users.noreply.github.com>2021-06-22 00:00:07 +0800
committerGitHub <noreply@github.com>2021-06-21 09:00:07 -0700
commitdf74d205071cb29ab23911012e79e03458a029db (patch)
treec7bddffda185c4ee046d4e65b30aef8c9feb8b12 /src/agent
parent6a93350ac05abdda54ebf41b62916e6d8217508b (diff)
downloadot-br-posix-df74d205071cb29ab23911012e79e03458a029db.tar.gz
[adproxy] re-register all services when the mDNS publisher becomes ready (#888)
When mDNS daemon restarts, the mDNS library may need to re-advertise all hosts and services. This commit extracts this functionality and makes it a public method. Also, on kReady, SRP server will publish all registered hosts and services. This is helpful when the advertising proxy reconnects to the mDNS provider.
Diffstat (limited to 'src/agent')
-rw-r--r--src/agent/advertising_proxy.cpp181
-rw-r--r--src/agent/advertising_proxy.hpp21
-rw-r--r--src/agent/border_agent.cpp3
3 files changed, 126 insertions, 79 deletions
diff --git a/src/agent/advertising_proxy.cpp b/src/agent/advertising_proxy.cpp
index 18a8f3ed..493a8c82 100644
--- a/src/agent/advertising_proxy.cpp
+++ b/src/agent/advertising_proxy.cpp
@@ -136,93 +136,19 @@ void AdvertisingProxy::AdvertisingHandler(otSrpServerServiceUpdateId aId,
const otSrpServerHost * aHost,
uint32_t aTimeout)
{
- // TODO: There are corner cases that the `aHost` is freed by SRP server because
- // of timeout, but this `aHost` is passed back to SRP server and matches a newly
- // allocated otSrpServerHost object which has the same pointer value as this
- // `aHost`. This results in mismatching of the outstanding SRP updates. Solutions
- // are cleaning up the outstanding update entries before timing out or using
- // incremental ID to match oustanding SRP updates.
OTBR_UNUSED_VARIABLE(aTimeout);
- otbrError error = OTBR_ERROR_NONE;
- const char * fullHostName;
- std::string hostName;
- std::string hostDomain;
- const otIp6Address * hostAddress;
- uint8_t hostAddressNum;
- bool hostDeleted;
- const otSrpServerService *service;
- OutstandingUpdate * update;
-
- mOutstandingUpdates.resize(mOutstandingUpdates.size() + 1);
- update = &mOutstandingUpdates.back();
-
- fullHostName = otSrpServerHostGetFullName(aHost);
-
- otbrLogInfo("Advertise SRP service updates: host=%s", fullHostName);
-
- SuccessOrExit(error = SplitFullHostName(fullHostName, hostName, hostDomain));
- hostAddress = otSrpServerHostGetAddresses(aHost, &hostAddressNum);
- hostDeleted = otSrpServerHostIsDeleted(aHost);
+ OutstandingUpdate *update = nullptr;
+ otbrError error = OTBR_ERROR_NONE;
+ mOutstandingUpdates.emplace_back();
+ update = &mOutstandingUpdates.back();
update->mId = aId;
- update->mCallbackCount += !hostDeleted;
- update->mHostName = hostName;
-
- service = nullptr;
- while ((service = otSrpServerHostGetNextService(aHost, service)) != nullptr)
- {
- update->mCallbackCount += !hostDeleted && !otSrpServerServiceIsDeleted(service);
- }
- if (!hostDeleted)
- {
- // TODO: select a preferred address or advertise all addresses from SRP client.
- otbrLogInfo("Publish SRP host: %s", fullHostName);
- SuccessOrExit(error =
- mPublisher.PublishHost(hostName.c_str(), hostAddress[0].mFields.m8, sizeof(hostAddress[0])));
- }
- else
- {
- otbrLogInfo("Unpublish SRP host: %s", fullHostName);
- SuccessOrExit(error = mPublisher.UnpublishHost(hostName.c_str()));
- }
+ error = PublishHostAndItsServices(aHost, update);
- service = nullptr;
- while ((service = otSrpServerHostGetNextService(aHost, service)) != nullptr)
- {
- const char *fullServiceName = otSrpServerServiceGetFullName(service);
- std::string serviceName;
- std::string serviceType;
- std::string serviceDomain;
-
- SuccessOrExit(error = SplitFullServiceInstanceName(fullServiceName, serviceName, serviceType, serviceDomain));
-
- update->mServiceNames.emplace_back(serviceName, serviceType);
-
- if (!hostDeleted && !otSrpServerServiceIsDeleted(service))
- {
- Mdns::Publisher::TxtList txtList = MakeTxtList(service);
-
- otbrLogInfo("Publish SRP service: %s", fullServiceName);
- SuccessOrExit(error = mPublisher.PublishService(hostName.c_str(), otSrpServerServiceGetPort(service),
- serviceName.c_str(), serviceType.c_str(), txtList));
- }
- else
- {
- otbrLogInfo("Unpublish SRP service: %s", fullServiceName);
- SuccessOrExit(error = mPublisher.UnpublishService(serviceName.c_str(), serviceType.c_str()));
- }
- }
-
-exit:
if (error != OTBR_ERROR_NONE || update->mCallbackCount == 0)
{
- if (error != OTBR_ERROR_NONE)
- {
- otbrLogInfo("Failed to advertise SRP service updates %p", aHost);
- }
-
mOutstandingUpdates.pop_back();
otSrpServerHandleServiceUpdateResult(GetInstance(), aId, OtbrErrorToOtError(error));
}
@@ -306,6 +232,103 @@ exit:
}
}
+void AdvertisingProxy::PublishAllHostsAndServices(void)
+{
+ const otSrpServerHost *host = nullptr;
+
+ VerifyOrExit(mPublisher.IsStarted(), mPublisher.Start());
+
+ otbrLogInfo("Publish all hosts and services");
+ while ((host = otSrpServerGetNextHost(GetInstance(), host)))
+ {
+ PublishHostAndItsServices(host, nullptr);
+ }
+
+exit:
+ return;
+}
+
+otbrError AdvertisingProxy::PublishHostAndItsServices(const otSrpServerHost *aHost, OutstandingUpdate *aUpdate)
+{
+ otbrError error = OTBR_ERROR_NONE;
+ const char * fullHostName;
+ std::string hostName;
+ std::string hostDomain;
+ const otIp6Address * hostAddress;
+ uint8_t hostAddressNum;
+ bool hostDeleted;
+ const otSrpServerService *service;
+
+ fullHostName = otSrpServerHostGetFullName(aHost);
+
+ otbrLogInfo("Advertise SRP service updates: host=%s", fullHostName);
+
+ SuccessOrExit(error = SplitFullHostName(fullHostName, hostName, hostDomain));
+ hostAddress = otSrpServerHostGetAddresses(aHost, &hostAddressNum);
+ hostDeleted = otSrpServerHostIsDeleted(aHost);
+
+ if (aUpdate)
+ {
+ aUpdate->mCallbackCount += !hostDeleted;
+ aUpdate->mHostName = hostName;
+ service = nullptr;
+ while ((service = otSrpServerHostGetNextService(aHost, service)))
+ {
+ aUpdate->mCallbackCount += !hostDeleted && !otSrpServerServiceIsDeleted(service);
+ }
+ }
+
+ if (!hostDeleted)
+ {
+ // TODO: select a preferred address or advertise all addresses from SRP client.
+ otbrLogInfo("Publish SRP host: %s", fullHostName);
+ SuccessOrExit(error =
+ mPublisher.PublishHost(hostName.c_str(), hostAddress[0].mFields.m8, sizeof(hostAddress[0])));
+ }
+ else
+ {
+ otbrLogInfo("Unpublish SRP host: %s", fullHostName);
+ SuccessOrExit(error = mPublisher.UnpublishHost(hostName.c_str()));
+ }
+
+ service = nullptr;
+ while ((service = otSrpServerHostGetNextService(aHost, service)))
+ {
+ const char *fullServiceName = otSrpServerServiceGetFullName(service);
+ std::string serviceName;
+ std::string serviceType;
+ std::string serviceDomain;
+
+ SuccessOrExit(error = SplitFullServiceInstanceName(fullServiceName, serviceName, serviceType, serviceDomain));
+
+ if (aUpdate)
+ {
+ aUpdate->mServiceNames.emplace_back(serviceName, serviceType);
+ }
+
+ if (!hostDeleted && !otSrpServerServiceIsDeleted(service))
+ {
+ Mdns::Publisher::TxtList txtList = MakeTxtList(service);
+
+ otbrLogInfo("Publish SRP service: %s", fullServiceName);
+ SuccessOrExit(error = mPublisher.PublishService(hostName.c_str(), otSrpServerServiceGetPort(service),
+ serviceName.c_str(), serviceType.c_str(), txtList));
+ }
+ else
+ {
+ otbrLogInfo("Unpublish SRP service: %s", fullServiceName);
+ SuccessOrExit(error = mPublisher.UnpublishService(serviceName.c_str(), serviceType.c_str()));
+ }
+ }
+
+exit:
+ if (error != OTBR_ERROR_NONE)
+ {
+ otbrLogInfo("Failed to advertise SRP service updates %p", aHost);
+ }
+ return error;
+}
+
Mdns::Publisher::TxtList AdvertisingProxy::MakeTxtList(const otSrpServerService *aSrpService)
{
const uint8_t * txtData;
diff --git a/src/agent/advertising_proxy.hpp b/src/agent/advertising_proxy.hpp
index dbe3f390..5e3483f8 100644
--- a/src/agent/advertising_proxy.hpp
+++ b/src/agent/advertising_proxy.hpp
@@ -77,6 +77,12 @@ public:
*/
void Stop();
+ /**
+ * This method publishes all registered hosts and services.
+ *
+ */
+ void PublishAllHostsAndServices(void);
+
private:
struct OutstandingUpdate
{
@@ -101,6 +107,21 @@ private:
static void PublishHostHandler(const char *aName, otbrError aError, void *aContext);
void PublishHostHandler(const char *aName, otbrError aError);
+ /**
+ * This method publishes a specified host and its services.
+ *
+ * It also makes a OutstandingUpdate object when needed.
+ *
+ * @param[in] aHost A pointer to the host.
+ * @param[in] aUpdate A pointer to the output OutstandingUpdate object. When it's not null, the method will
+ * fill its fields, otherwise it's ignored.
+ *
+ * @retval OTBR_ERROR_NONE Successfully published the host and its services.
+ * @retval ... Failed to publish the host and/or its services.
+ *
+ */
+ otbrError PublishHostAndItsServices(const otSrpServerHost *aHost, OutstandingUpdate *aUpdate);
+
otInstance *GetInstance(void) { return mNcp.GetInstance(); }
// A reference to the NCP controller, has no ownership.
diff --git a/src/agent/border_agent.cpp b/src/agent/border_agent.cpp
index 0908f582..63ce114f 100644
--- a/src/agent/border_agent.cpp
+++ b/src/agent/border_agent.cpp
@@ -190,6 +190,9 @@ void BorderAgent::HandleMdnsState(Mdns::Publisher::State aState)
{
case Mdns::Publisher::State::kReady:
UpdateMeshCopService();
+#if OTBR_ENABLE_SRP_ADVERTISING_PROXY
+ mAdvertisingProxy.PublishAllHostsAndServices();
+#endif
break;
default:
otbrLogWarning("MDNS service not available!");