diff options
author | whd <7058128+superwhd@users.noreply.github.com> | 2021-06-22 00:00:07 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-21 09:00:07 -0700 |
commit | df74d205071cb29ab23911012e79e03458a029db (patch) | |
tree | c7bddffda185c4ee046d4e65b30aef8c9feb8b12 /src/agent | |
parent | 6a93350ac05abdda54ebf41b62916e6d8217508b (diff) | |
download | ot-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.cpp | 181 | ||||
-rw-r--r-- | src/agent/advertising_proxy.hpp | 21 | ||||
-rw-r--r-- | src/agent/border_agent.cpp | 3 |
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!"); |