mirror of
https://github.com/espressif/openthread.git
synced 2026-10-23 07:58:20 +00:00
[mdns] lazily discover ServiceEntry compression offsets and host (#13696)
This commit replaces the upfront `DiscoverOffsetsAndHost()` call in `ServiceEntry::PrepareProbe()` and `ServiceEntry::PrepareResponseRecords()` with on-demand discovery helpers invoked only when the corresponding names or records are actually appended: - `DiscoverHost()` to find and cache the associated `HostEntry` in `mHostEntry` (cleared in `ClearAppendState()`) and sync host name compression offsets between `ServiceEntry` and `HostEntry`. - `DiscoverServiceTypeCompressOffset()`, `DiscoverSubServiceNameCompressOffsetFor()`, and `DiscoverHostNameCompressOffset()` (using a common `DiscoverCompressOffset()` helper) invoked from the respective `Append*To()` methods. This avoids unnecessary scans over `mHostEntries` and `mServiceEntries` when a `ServiceEntry` does not append records or only appends a subset of records.
This commit is contained in:
+127
-72
@@ -2568,6 +2568,7 @@ Core::ServiceEntry::ServiceEntry(void)
|
||||
, mPriority(0)
|
||||
, mWeight(0)
|
||||
, mPort(0)
|
||||
, mHostEntry(nullptr)
|
||||
, mIsAddedInServiceTypes(false)
|
||||
{
|
||||
}
|
||||
@@ -2894,6 +2895,7 @@ void Core::ServiceEntry::ClearAppendState(void)
|
||||
mServiceTypeOffset.Clear();
|
||||
mSubServiceTypeOffset.Clear();
|
||||
mHostNameOffset.Clear();
|
||||
mHostEntry = nullptr;
|
||||
|
||||
for (SubType &subType : mSubTypes)
|
||||
{
|
||||
@@ -2908,12 +2910,8 @@ void Core::ServiceEntry::PrepareProbe(TxMessage &aProbe)
|
||||
|
||||
do
|
||||
{
|
||||
HostEntry *hostEntry = nullptr;
|
||||
|
||||
aProbe.SaveCurrentState();
|
||||
|
||||
DiscoverOffsetsAndHost(hostEntry);
|
||||
|
||||
AppendServiceNameTo(aProbe, kQuestionSection);
|
||||
AppendQuestionTo(aProbe);
|
||||
|
||||
@@ -2963,11 +2961,8 @@ void Core::ServiceEntry::PrepareResponseRecords(EntryContext &aContext)
|
||||
{
|
||||
bool appendNsec = false;
|
||||
bool appendAdditionalRecordsForPtr = false;
|
||||
HostEntry *hostEntry = nullptr;
|
||||
TxMessage &response = aContext.mResponseMessage;
|
||||
|
||||
DiscoverOffsetsAndHost(hostEntry);
|
||||
|
||||
// We determine records to include in Additional Data section
|
||||
// per RFC 6763 section 12:
|
||||
//
|
||||
@@ -3010,11 +3005,7 @@ void Core::ServiceEntry::PrepareResponseRecords(EntryContext &aContext)
|
||||
{
|
||||
mSrvRecord.MarkToAppendInAdditionalData();
|
||||
mTxtRecord.MarkToAppendInAdditionalData();
|
||||
|
||||
if (hostEntry != nullptr)
|
||||
{
|
||||
hostEntry->MarkToAppendAddrRecordsInAdditionalData();
|
||||
}
|
||||
MarkToAppendHostAddrRecordsInAdditionalData();
|
||||
}
|
||||
|
||||
if (mSrvRecord.ShouldAppendTo(aContext))
|
||||
@@ -3022,9 +3013,9 @@ void Core::ServiceEntry::PrepareResponseRecords(EntryContext &aContext)
|
||||
AppendSrvRecordTo(response, kAnswerSection);
|
||||
appendNsec = true;
|
||||
|
||||
if ((mSrvRecord.GetTtl() > 0) && (hostEntry != nullptr))
|
||||
if (mSrvRecord.GetTtl() > 0)
|
||||
{
|
||||
hostEntry->MarkToAppendAddrRecordsInAdditionalData();
|
||||
MarkToAppendHostAddrRecordsInAdditionalData();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3052,16 +3043,17 @@ void Core::ServiceEntry::PrepareResponseRecords(EntryContext &aContext)
|
||||
AppendTxtRecordTo(response, kAdditionalDataSection);
|
||||
}
|
||||
|
||||
if (hostEntry != nullptr)
|
||||
if (mHostEntry != nullptr)
|
||||
{
|
||||
if (hostEntry->mIp6AddrRecord.ShouldAppendInAdditionalDataSection())
|
||||
if (mHostEntry->mIp6AddrRecord.ShouldAppendInAdditionalDataSection())
|
||||
{
|
||||
hostEntry->AppendIp6AddressRecordsTo(response, kAdditionalDataSection);
|
||||
mHostEntry->AppendIp6AddressRecordsTo(response, kAdditionalDataSection);
|
||||
}
|
||||
|
||||
if ((hostEntry->mIp4AddrRecord != nullptr) && hostEntry->mIp4AddrRecord->ShouldAppendInAdditionalDataSection())
|
||||
if ((mHostEntry->mIp4AddrRecord != nullptr) &&
|
||||
mHostEntry->mIp4AddrRecord->ShouldAppendInAdditionalDataSection())
|
||||
{
|
||||
hostEntry->AppendIp4AddressRecordsTo(response, kAdditionalDataSection);
|
||||
mHostEntry->AppendIp4AddressRecordsTo(response, kAdditionalDataSection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3130,26 +3122,36 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Core::ServiceEntry::DiscoverOffsetsAndHost(HostEntry *&aHostEntry)
|
||||
void Core::ServiceEntry::MarkToAppendHostAddrRecordsInAdditionalData(void)
|
||||
{
|
||||
// Discovers the `HostEntry` associated with this `ServiceEntry`
|
||||
// and name compression offsets from the previously appended
|
||||
// entries.
|
||||
DiscoverHost();
|
||||
|
||||
// TODO: Need to handle name matching host name
|
||||
|
||||
aHostEntry = Get<Core>().mHostEntries.FindMatching(mHostName);
|
||||
|
||||
if ((aHostEntry != nullptr) && (aHostEntry->GetState() != GetState()))
|
||||
if (mHostEntry != nullptr)
|
||||
{
|
||||
aHostEntry = nullptr;
|
||||
mHostEntry->MarkToAppendAddrRecordsInAdditionalData();
|
||||
}
|
||||
}
|
||||
|
||||
void Core::ServiceEntry::DiscoverHost(void)
|
||||
{
|
||||
if (mHostEntry == nullptr)
|
||||
{
|
||||
mHostEntry = Get<Core>().mHostEntries.FindMatching(mHostName);
|
||||
|
||||
if ((mHostEntry != nullptr) && (mHostEntry->GetState() != GetState()))
|
||||
{
|
||||
mHostEntry = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (aHostEntry != nullptr)
|
||||
if (mHostEntry != nullptr)
|
||||
{
|
||||
mHostNameOffset.UpdateFrom(aHostEntry->mNameOffset);
|
||||
mHostNameOffset.UpdateFrom(mHostEntry->mNameOffset);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::ServiceEntry::DiscoverCompressOffset(OffsetDiscoverer aDiscoverer, void *aContext)
|
||||
{
|
||||
for (ServiceEntry &other : Get<Core>().mServiceEntries)
|
||||
{
|
||||
// We only need to search up to `this` entry in the list,
|
||||
@@ -3170,38 +3172,93 @@ void Core::ServiceEntry::DiscoverOffsetsAndHost(HostEntry *&aHostEntry)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NameMatch(mHostName, other.mHostName))
|
||||
if ((this->*aDiscoverer)(other, aContext))
|
||||
{
|
||||
mHostNameOffset.UpdateFrom(other.mHostNameOffset);
|
||||
}
|
||||
|
||||
if (NameMatch(mServiceType, other.mServiceType))
|
||||
{
|
||||
mServiceTypeOffset.UpdateFrom(other.mServiceTypeOffset);
|
||||
|
||||
if (GetState() == kProbing)
|
||||
{
|
||||
// No need to search for sub-type service offsets when
|
||||
// we are still probing.
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
mSubServiceTypeOffset.UpdateFrom(other.mSubServiceTypeOffset);
|
||||
|
||||
for (SubType &subType : mSubTypes)
|
||||
{
|
||||
const SubType *otherSubType = other.mSubTypes.FindMatching(subType.mLabel.AsCString());
|
||||
|
||||
if (otherSubType != nullptr)
|
||||
{
|
||||
subType.mSubServiceNameOffset.UpdateFrom(otherSubType->mSubServiceNameOffset);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Core::ServiceEntry::DiscoverServiceTypeCompressOffset(void)
|
||||
{
|
||||
if (!mServiceTypeOffset.IsKnown())
|
||||
{
|
||||
DiscoverCompressOffset(&ServiceEntry::DiscoverServiceTypeOffsetFrom);
|
||||
}
|
||||
}
|
||||
|
||||
bool Core::ServiceEntry::DiscoverServiceTypeOffsetFrom(const ServiceEntry &aOther, void *aContext)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aContext);
|
||||
|
||||
if (NameMatch(mServiceType, aOther.mServiceType))
|
||||
{
|
||||
mServiceTypeOffset.UpdateFrom(aOther.mServiceTypeOffset);
|
||||
mSubServiceTypeOffset.UpdateFrom(aOther.mSubServiceTypeOffset);
|
||||
}
|
||||
|
||||
return mServiceTypeOffset.IsKnown();
|
||||
}
|
||||
|
||||
void Core::ServiceEntry::DiscoverHostNameCompressOffset(void)
|
||||
{
|
||||
VerifyOrExit(!mHostNameOffset.IsKnown());
|
||||
|
||||
DiscoverHost();
|
||||
VerifyOrExit(!mHostNameOffset.IsKnown());
|
||||
|
||||
DiscoverCompressOffset(&ServiceEntry::DiscoverHostNameOffsetFrom);
|
||||
|
||||
if (mHostEntry != nullptr)
|
||||
{
|
||||
mHostEntry->mNameOffset.UpdateFrom(mHostNameOffset);
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
bool Core::ServiceEntry::DiscoverHostNameOffsetFrom(const ServiceEntry &aOther, void *aContext)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aContext);
|
||||
|
||||
if (NameMatch(mHostName, aOther.mHostName))
|
||||
{
|
||||
mHostNameOffset.UpdateFrom(aOther.mHostNameOffset);
|
||||
}
|
||||
|
||||
return mHostNameOffset.IsKnown();
|
||||
}
|
||||
|
||||
void Core::ServiceEntry::DiscoverSubServiceNameCompressOffsetFor(SubType &aSubType)
|
||||
{
|
||||
if (!aSubType.mSubServiceNameOffset.IsKnown())
|
||||
{
|
||||
DiscoverCompressOffset(&ServiceEntry::DiscoverSubServiceNameOffsetFrom, &aSubType);
|
||||
}
|
||||
}
|
||||
|
||||
bool Core::ServiceEntry::DiscoverSubServiceNameOffsetFrom(const ServiceEntry &aOther, void *aContext)
|
||||
{
|
||||
SubType *subType = static_cast<SubType *>(aContext);
|
||||
const SubType *otherSubType;
|
||||
|
||||
VerifyOrExit(NameMatch(mServiceType, aOther.mServiceType));
|
||||
|
||||
mServiceTypeOffset.UpdateFrom(aOther.mServiceTypeOffset);
|
||||
mSubServiceTypeOffset.UpdateFrom(aOther.mSubServiceTypeOffset);
|
||||
|
||||
VerifyOrExit(aOther.mSubServiceTypeOffset.IsKnown());
|
||||
|
||||
otherSubType = aOther.mSubTypes.FindMatching(subType->mLabel.AsCString());
|
||||
|
||||
VerifyOrExit(otherSubType != nullptr);
|
||||
subType->mSubServiceNameOffset.UpdateFrom(otherSubType->mSubServiceNameOffset);
|
||||
|
||||
exit:
|
||||
return subType->mSubServiceNameOffset.IsKnown();
|
||||
}
|
||||
|
||||
void Core::ServiceEntry::UpdateServiceTypes(void)
|
||||
{
|
||||
// This method updates the `mServiceTypes` list adding or
|
||||
@@ -3411,30 +3468,22 @@ exit:
|
||||
|
||||
void Core::ServiceEntry::AppendServiceTypeTo(TxMessage &aTxMessage, Section aSection)
|
||||
{
|
||||
DiscoverServiceTypeCompressOffset();
|
||||
aTxMessage.AppendServiceType(aSection, mServiceType.AsCString(), mServiceTypeOffset);
|
||||
}
|
||||
|
||||
void Core::ServiceEntry::AppendSubServiceTypeTo(TxMessage &aTxMessage, Section aSection)
|
||||
{
|
||||
AppendOutcome outcome;
|
||||
|
||||
outcome = aTxMessage.AppendLabel(aSection, kSubServiceLabel, mSubServiceTypeOffset);
|
||||
VerifyOrExit(outcome != kAppendedFullNameAsCompressed);
|
||||
|
||||
AppendServiceTypeTo(aTxMessage, aSection);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Core::ServiceEntry::AppendSubServiceNameTo(TxMessage &aTxMessage, Section aSection, SubType &aSubType)
|
||||
{
|
||||
AppendOutcome outcome;
|
||||
|
||||
DiscoverSubServiceNameCompressOffsetFor(aSubType);
|
||||
outcome = aTxMessage.AppendLabel(aSection, aSubType.mLabel.AsCString(), aSubType.mSubServiceNameOffset);
|
||||
VerifyOrExit(outcome != kAppendedFullNameAsCompressed);
|
||||
|
||||
AppendSubServiceTypeTo(aTxMessage, aSection);
|
||||
outcome = aTxMessage.AppendLabel(aSection, kSubServiceLabel, mSubServiceTypeOffset);
|
||||
VerifyOrExit(outcome != kAppendedFullNameAsCompressed);
|
||||
|
||||
aTxMessage.AppendServiceType(aSection, mServiceType.AsCString(), mServiceTypeOffset);
|
||||
|
||||
exit:
|
||||
return;
|
||||
@@ -3444,9 +3493,15 @@ void Core::ServiceEntry::AppendHostNameTo(TxMessage &aTxMessage, Section aSectio
|
||||
{
|
||||
AppendOutcome outcome;
|
||||
|
||||
DiscoverHostNameCompressOffset();
|
||||
outcome = aTxMessage.AppendMultipleLabels(aSection, mHostName.AsCString(), mHostNameOffset);
|
||||
VerifyOrExit(outcome != kAppendedFullNameAsCompressed);
|
||||
|
||||
if (mHostEntry != nullptr)
|
||||
{
|
||||
mHostEntry->mNameOffset.UpdateFrom(mHostNameOffset);
|
||||
}
|
||||
|
||||
aTxMessage.AppendDomainName(aSection);
|
||||
|
||||
exit:
|
||||
|
||||
+12
-2
@@ -1409,6 +1409,8 @@ private:
|
||||
#endif
|
||||
|
||||
private:
|
||||
typedef bool (ServiceEntry::*OffsetDiscoverer)(const ServiceEntry &aOther, void *aContext);
|
||||
|
||||
class SubType : public LinkedListEntry<SubType>, public Heap::Allocatable<SubType>, private ot::NonCopyable
|
||||
{
|
||||
public:
|
||||
@@ -1431,7 +1433,15 @@ private:
|
||||
void PrepareResponseRecords(EntryContext &aContext);
|
||||
void UpdateRecordsState(const TxMessage &aResponse);
|
||||
void DetermineNextFireTime(void);
|
||||
void DiscoverOffsetsAndHost(HostEntry *&aHost);
|
||||
void MarkToAppendHostAddrRecordsInAdditionalData(void);
|
||||
void DiscoverHost(void);
|
||||
void DiscoverCompressOffset(OffsetDiscoverer aDiscoverer, void *aContext = nullptr);
|
||||
void DiscoverServiceTypeCompressOffset(void);
|
||||
bool DiscoverServiceTypeOffsetFrom(const ServiceEntry &aOther, void *aContext);
|
||||
void DiscoverHostNameCompressOffset(void);
|
||||
bool DiscoverHostNameOffsetFrom(const ServiceEntry &aOther, void *aContext);
|
||||
void DiscoverSubServiceNameCompressOffsetFor(SubType &aSubType);
|
||||
bool DiscoverSubServiceNameOffsetFrom(const ServiceEntry &aOther, void *aContext);
|
||||
void UpdateServiceTypes(void);
|
||||
void AppendSrvRecordTo(TxMessage &aTxMessage, Section aSection);
|
||||
void AppendTxtRecordTo(TxMessage &aTxMessage, Section aSection);
|
||||
@@ -1440,7 +1450,6 @@ private:
|
||||
void AppendNsecRecordTo(TxMessage &aTxMessage, Section aSection);
|
||||
void AppendServiceNameTo(TxMessage &TxMessage, Section aSection, bool aPerformNameCompression = true);
|
||||
void AppendServiceTypeTo(TxMessage &aTxMessage, Section aSection);
|
||||
void AppendSubServiceTypeTo(TxMessage &aTxMessage, Section aSection);
|
||||
void AppendSubServiceNameTo(TxMessage &aTxMessage, Section aSection, SubType &aSubType);
|
||||
void AppendHostNameTo(TxMessage &aTxMessage, Section aSection);
|
||||
|
||||
@@ -1464,6 +1473,7 @@ private:
|
||||
CompressOffset mServiceTypeOffset;
|
||||
CompressOffset mSubServiceTypeOffset;
|
||||
CompressOffset mHostNameOffset;
|
||||
HostEntry *mHostEntry;
|
||||
bool mIsAddedInServiceTypes;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user