Skip to content

Commit

Permalink
[mdns] change PublishService() to get encoded TXT data as input (#1996
Browse files Browse the repository at this point in the history
)

This commit updates `Mdns::Publisher::PublishService()` to take
encoded TXT data as its input, harmonizing the `Publish` API with the
`Subscribe` API, which also uses encoded TXT data. This makes it
easier to use with advertising proxy and TREL, avoiding the extra
step of decoding already encoded TXT data to call `PublishService()`.
  • Loading branch information
abtink authored Sep 6, 2023
1 parent 4f580b9 commit 8cd9127
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 100 deletions.
9 changes: 8 additions & 1 deletion src/border_agent/border_agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,11 @@ void BorderAgent::PublishMeshCopService(void)
const otExtAddress *extAddr = otLinkGetExtendedAddress(instance);
const char *networkName = otThreadGetNetworkName(instance);
Mdns::Publisher::TxtList txtList{{"rv", "1"}};
Mdns::Publisher::TxtData txtData;
int port;
otbrError error;

OTBR_UNUSED_VARIABLE(error);

otbrLogInfo("Publish meshcop service %s.%s.local.", mServiceInstanceName.c_str(), kBorderAgentServiceType);

Expand Down Expand Up @@ -434,8 +438,11 @@ void BorderAgent::PublishMeshCopService(void)
port = kBorderAgentServiceDummyPort;
}

error = Mdns::Publisher::EncodeTxtData(txtList, txtData);
assert(error == OTBR_ERROR_NONE);

mPublisher->PublishService(/* aHostName */ "", mServiceInstanceName, kBorderAgentServiceType,
Mdns::Publisher::SubTypeList{}, port, txtList, [this](otbrError aError) {
Mdns::Publisher::SubTypeList{}, port, txtData, [this](otbrError aError) {
if (aError == OTBR_ERROR_ABORTED)
{
// OTBR_ERROR_ABORTED is thrown when an ongoing service registration is
Expand Down
19 changes: 6 additions & 13 deletions src/mdns/mdns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ void Publisher::PublishService(const std::string &aHostName,
const std::string &aType,
const SubTypeList &aSubTypeList,
uint16_t aPort,
const TxtList &aTxtList,
const TxtData &aTxtData,
ResultCallback &&aCallback)
{
otbrError error;

mServiceRegistrationBeginTime[std::make_pair(aName, aType)] = Clock::now();

error = PublishServiceImpl(aHostName, aName, aType, aSubTypeList, aPort, aTxtList, std::move(aCallback));
error = PublishServiceImpl(aHostName, aName, aType, aSubTypeList, aPort, aTxtData, std::move(aCallback));
if (error != OTBR_ERROR_NONE)
{
UpdateMdnsResponseCounters(mTelemetryInfo.mServiceRegistrations, error);
Expand Down Expand Up @@ -280,13 +280,6 @@ Publisher::SubTypeList Publisher::SortSubTypeList(SubTypeList aSubTypeList)
return aSubTypeList;
}

Publisher::TxtList Publisher::SortTxtList(TxtList aTxtList)
{
std::sort(aTxtList.begin(), aTxtList.end(),
[](const TxtEntry &aLhs, const TxtEntry &aRhs) { return aLhs.mKey < aRhs.mKey; });
return aTxtList;
}

Publisher::AddressList Publisher::SortAddressList(AddressList aAddressList)
{
std::sort(aAddressList.begin(), aAddressList.end());
Expand Down Expand Up @@ -339,14 +332,14 @@ Publisher::ResultCallback Publisher::HandleDuplicateServiceRegistration(const st
const std::string &aType,
const SubTypeList &aSubTypeList,
uint16_t aPort,
const TxtList &aTxtList,
const TxtData &aTxtData,
ResultCallback &&aCallback)
{
ServiceRegistration *serviceReg = FindServiceRegistration(aName, aType);

VerifyOrExit(serviceReg != nullptr);

if (serviceReg->IsOutdated(aHostName, aName, aType, aSubTypeList, aPort, aTxtList))
if (serviceReg->IsOutdated(aHostName, aName, aType, aSubTypeList, aPort, aTxtData))
{
otbrLogInfo("Removing existing service %s.%s: outdated", aName.c_str(), aType.c_str());
RemoveServiceRegistration(aName, aType, OTBR_ERROR_ABORTED);
Expand Down Expand Up @@ -454,10 +447,10 @@ bool Publisher::ServiceRegistration::IsOutdated(const std::string &aHostName,
const std::string &aType,
const SubTypeList &aSubTypeList,
uint16_t aPort,
const TxtList &aTxtList) const
const TxtData &aTxtData) const
{
return !(mHostName == aHostName && mName == aName && mType == aType && mSubTypeList == aSubTypeList &&
mPort == aPort && mTxtList == aTxtList);
mPort == aPort && mTxtData == aTxtData);
}

void Publisher::ServiceRegistration::Complete(otbrError aError)
Expand Down
40 changes: 20 additions & 20 deletions src/mdns/mdns.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ class Publisher : private NonCopyable
}
};

typedef std::vector<uint8_t> TxtData;
typedef std::vector<TxtEntry> TxtList;
typedef std::vector<std::string> SubTypeList;
typedef std::vector<Ip6Address> AddressList;
Expand All @@ -124,16 +125,16 @@ class Publisher : private NonCopyable
*/
struct DiscoveredInstanceInfo
{
bool mRemoved = false; ///< The Service Instance is removed.
uint32_t mNetifIndex = 0; ///< Network interface.
std::string mName; ///< Instance name.
std::string mHostName; ///< Full host name.
std::vector<Ip6Address> mAddresses; ///< IPv6 addresses.
uint16_t mPort = 0; ///< Port.
uint16_t mPriority = 0; ///< Service priority.
uint16_t mWeight = 0; ///< Service weight.
std::vector<uint8_t> mTxtData; ///< TXT RDATA bytes.
uint32_t mTtl = 0; ///< Service TTL.
bool mRemoved = false; ///< The Service Instance is removed.
uint32_t mNetifIndex = 0; ///< Network interface.
std::string mName; ///< Instance name.
std::string mHostName; ///< Full host name.
AddressList mAddresses; ///< IPv6 addresses.
uint16_t mPort = 0; ///< Port.
uint16_t mPriority = 0; ///< Service priority.
uint16_t mWeight = 0; ///< Service weight.
TxtData mTxtData; ///< TXT RDATA bytes.
uint32_t mTtl = 0; ///< Service TTL.
};

/**
Expand Down Expand Up @@ -213,7 +214,7 @@ class Publisher : private NonCopyable
* @param[in] aType The type of this service.
* @param[in] aSubTypeList A list of service subtypes.
* @param[in] aPort The port number of this service.
* @param[in] aTxtList A list of TXT name/value pairs.
* @param[in] aTxtData The encoded TXT data for this service.
* @param[in] aCallback The callback for receiving the publishing result. `OTBR_ERROR_NONE` will be
* returned if the operation is successful and all other values indicate a
* failure. Specifically, `OTBR_ERROR_DUPLICATED` indicates that the name has
Expand All @@ -226,7 +227,7 @@ class Publisher : private NonCopyable
const std::string &aType,
const SubTypeList &aSubTypeList,
uint16_t aPort,
const TxtList &aTxtList,
const TxtData &aTxtData,
ResultCallback &&aCallback);

/**
Expand Down Expand Up @@ -381,7 +382,7 @@ class Publisher : private NonCopyable
* @sa DecodeTxtData
*
*/
static otbrError EncodeTxtData(const TxtList &aTxtList, std::vector<uint8_t> &aTxtData);
static otbrError EncodeTxtData(const TxtList &aTxtList, TxtData &aTxtData);

/**
* This function decodes a TXT entry list from a TXT data buffer.
Expand Down Expand Up @@ -441,14 +442,14 @@ class Publisher : private NonCopyable
std::string mType;
SubTypeList mSubTypeList;
uint16_t mPort;
TxtList mTxtList;
TxtData mTxtData;

ServiceRegistration(std::string aHostName,
std::string aName,
std::string aType,
SubTypeList aSubTypeList,
uint16_t aPort,
TxtList aTxtList,
TxtData aTxtData,
ResultCallback &&aCallback,
Publisher *aPublisher)
: Registration(std::move(aCallback), aPublisher)
Expand All @@ -457,7 +458,7 @@ class Publisher : private NonCopyable
, mType(std::move(aType))
, mSubTypeList(SortSubTypeList(std::move(aSubTypeList)))
, mPort(aPort)
, mTxtList(SortTxtList(std::move(aTxtList)))
, mTxtData(std::move(aTxtData))
{
}
~ServiceRegistration(void) override { OnComplete(OTBR_ERROR_ABORTED); }
Expand All @@ -472,7 +473,7 @@ class Publisher : private NonCopyable
const std::string &aType,
const SubTypeList &aSubTypeList,
uint16_t aPort,
const TxtList &aTxtList) const;
const TxtData &aTxtData) const;
};

class HostRegistration : public Registration
Expand Down Expand Up @@ -504,7 +505,6 @@ class Publisher : private NonCopyable
using HostRegistrationMap = std::map<std::string, HostRegistrationPtr>;

static SubTypeList SortSubTypeList(SubTypeList aSubTypeList);
static TxtList SortTxtList(TxtList aTxtList);
static AddressList SortAddressList(AddressList aAddressList);
static std::string MakeFullServiceName(const std::string &aName, const std::string &aType);
static std::string MakeFullHostName(const std::string &aName);
Expand All @@ -514,7 +514,7 @@ class Publisher : private NonCopyable
const std::string &aType,
const SubTypeList &aSubTypeList,
uint16_t aPort,
const TxtList &aTxtList,
const TxtData &aTxtData,
ResultCallback &&aCallback) = 0;
virtual otbrError PublishHostImpl(const std::string &aName,
const std::vector<Ip6Address> &aAddresses,
Expand Down Expand Up @@ -544,7 +544,7 @@ class Publisher : private NonCopyable
const std::string &aType,
const SubTypeList &aSubTypeList,
uint16_t aPort,
const TxtList &aTxtList,
const TxtData &aTxtData,
ResultCallback &&aCallback);

ResultCallback HandleDuplicateHostRegistration(const std::string &aName,
Expand Down
18 changes: 10 additions & 8 deletions src/mdns/mdns_avahi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -639,13 +639,12 @@ otbrError PublisherAvahi::PublishServiceImpl(const std::string &aHostName,
const std::string &aType,
const SubTypeList &aSubTypeList,
uint16_t aPort,
const TxtList &aTxtList,
const TxtData &aTxtData,
ResultCallback &&aCallback)
{
otbrError error = OTBR_ERROR_NONE;
int avahiError = AVAHI_OK;
SubTypeList sortedSubTypeList = SortSubTypeList(aSubTypeList);
TxtList sortedTxtList = SortTxtList(aTxtList);
const std::string logHostName = !aHostName.empty() ? aHostName : "localhost";
std::string fullHostName;
std::string serviceName = aName;
Expand All @@ -667,11 +666,11 @@ otbrError PublisherAvahi::PublishServiceImpl(const std::string &aHostName,
serviceName = avahi_client_get_host_name(mClient);
}

aCallback = HandleDuplicateServiceRegistration(aHostName, serviceName, aType, sortedSubTypeList, aPort,
sortedTxtList, std::move(aCallback));
aCallback = HandleDuplicateServiceRegistration(aHostName, serviceName, aType, sortedSubTypeList, aPort, aTxtData,
std::move(aCallback));
VerifyOrExit(!aCallback.IsNull());

SuccessOrExit(error = TxtListToAvahiStringList(aTxtList, txtBuffer, sizeof(txtBuffer), txtHead));
SuccessOrExit(error = TxtDataToAvahiStringList(aTxtData, txtBuffer, sizeof(txtBuffer), txtHead));
VerifyOrExit((group = CreateGroup(mClient)) != nullptr, error = OTBR_ERROR_MDNS);
avahiError = avahi_entry_group_add_service_strlst(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AvahiPublishFlags{},
serviceName.c_str(), aType.c_str(),
Expand All @@ -693,7 +692,7 @@ otbrError PublisherAvahi::PublishServiceImpl(const std::string &aHostName,
VerifyOrExit(avahiError == AVAHI_OK);

AddServiceRegistration(std::unique_ptr<AvahiServiceRegistration>(new AvahiServiceRegistration(
aHostName, serviceName, aType, sortedSubTypeList, aPort, sortedTxtList, std::move(aCallback), group, this)));
aHostName, serviceName, aType, sortedSubTypeList, aPort, aTxtData, std::move(aCallback), group, this)));

exit:
if (avahiError != AVAHI_OK || error != OTBR_ERROR_NONE)
Expand Down Expand Up @@ -790,7 +789,7 @@ void PublisherAvahi::UnpublishHost(const std::string &aName, ResultCallback &&aC
std::move(aCallback)(error);
}

otbrError PublisherAvahi::TxtListToAvahiStringList(const TxtList &aTxtList,
otbrError PublisherAvahi::TxtDataToAvahiStringList(const TxtData &aTxtData,
AvahiStringList *aBuffer,
size_t aBufferSize,
AvahiStringList *&aHead)
Expand All @@ -799,9 +798,12 @@ otbrError PublisherAvahi::TxtListToAvahiStringList(const TxtList &aTxtList,
size_t used = 0;
AvahiStringList *last = nullptr;
AvahiStringList *curr = aBuffer;
TxtList txtList;

SuccessOrExit(error = DecodeTxtData(txtList, aTxtData.data(), aTxtData.size()));

aHead = nullptr;
for (const auto &txtEntry : aTxtList)
for (const auto &txtEntry : txtList)
{
const char *key = txtEntry.mKey.c_str();
size_t keyLength = txtEntry.mKey.length();
Expand Down
8 changes: 4 additions & 4 deletions src/mdns/mdns_avahi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class PublisherAvahi : public Publisher
const std::string &aType,
const SubTypeList &aSubTypeList,
uint16_t aPort,
const TxtList &aTxtList,
const TxtData &aTxtData,
ResultCallback &&aCallback) override;
otbrError PublishHostImpl(const std::string &aName,
const std::vector<Ip6Address> &aAddresses,
Expand All @@ -115,7 +115,7 @@ class PublisherAvahi : public Publisher
const std::string &aType,
const SubTypeList &aSubTypeList,
uint16_t aPort,
const TxtList &aTxtList,
const TxtData &aTxtData,
ResultCallback &&aCallback,
AvahiEntryGroup *aEntryGroup,
PublisherAvahi *aPublisher)
Expand All @@ -124,7 +124,7 @@ class PublisherAvahi : public Publisher
aType,
aSubTypeList,
aPort,
aTxtList,
aTxtData,
std::move(aCallback),
aPublisher)
, mEntryGroup(aEntryGroup)
Expand Down Expand Up @@ -340,7 +340,7 @@ class PublisherAvahi : public Publisher
void HandleGroupState(AvahiEntryGroup *aGroup, AvahiEntryGroupState aState);
void CallHostOrServiceCallback(AvahiEntryGroup *aGroup, otbrError aError);

static otbrError TxtListToAvahiStringList(const TxtList &aTxtList,
static otbrError TxtDataToAvahiStringList(const TxtData &aTxtData,
AvahiStringList *aBuffer,
size_t aBufferSize,
AvahiStringList *&aHead);
Expand Down
Loading

0 comments on commit 8cd9127

Please sign in to comment.