mirror of
https://github.com/espressif/openthread.git
synced 2026-08-13 22:27:47 +00:00
[mdns] add support for legacy unicast response feature (#10053)
Signed-off-by: Cristib05 <[email protected]>
This commit is contained in:
+105
-38
@@ -391,12 +391,13 @@ bool Core::NameMatch(const Heap::String &aFirst, const Heap::String &aSecond)
|
||||
return !aSecond.IsNull() && NameMatch(aFirst, aSecond.AsCString());
|
||||
}
|
||||
|
||||
void Core::UpdateCacheFlushFlagIn(ResourceRecord &aResourceRecord, Section aSection)
|
||||
void Core::UpdateCacheFlushFlagIn(ResourceRecord &aResourceRecord, Section aSection, bool aIsLegacyUnicast)
|
||||
{
|
||||
// Do not set the cache-flush flag is the record is
|
||||
// appended in Authority Section in a probe message.
|
||||
// Do not set the cache-flush flag if the record is
|
||||
// appended in Authority Section in a probe message,
|
||||
// or is intended for a Legacy Unicast response.
|
||||
|
||||
if (aSection != kAuthoritySection)
|
||||
if (aSection != kAuthoritySection && !aIsLegacyUnicast)
|
||||
{
|
||||
aResourceRecord.SetClass(aResourceRecord.GetClass() | kClassCacheFlushFlag);
|
||||
}
|
||||
@@ -579,6 +580,11 @@ void Core::RecordInfo::UpdateProperty(AddressArray &aAddrProperty, const Ip6::Ad
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Core::RecordInfo::GetTtl(bool aIsLegacyUnicast) const
|
||||
{
|
||||
return aIsLegacyUnicast ? Min(kMaxLegacyUnicastTtl, mTtl) : mTtl;
|
||||
}
|
||||
|
||||
void Core::RecordInfo::UpdateTtl(uint32_t aTtl) { return UpdateProperty(mTtl, aTtl); }
|
||||
|
||||
void Core::RecordInfo::StartAnnouncing(void)
|
||||
@@ -596,7 +602,7 @@ void Core::RecordInfo::ScheduleAnswer(const AnswerInfo &aInfo)
|
||||
{
|
||||
VerifyOrExit(CanAnswer());
|
||||
|
||||
if (aInfo.mUnicastResponse)
|
||||
if (aInfo.mUnicastResponse || aInfo.mLegacyUnicastResponse)
|
||||
{
|
||||
mUnicastAnswerPending = true;
|
||||
ExitNow();
|
||||
@@ -647,6 +653,7 @@ bool Core::RecordInfo::ShouldAppendTo(TxMessage &aResponse, TimeMilli aNow) cons
|
||||
break;
|
||||
|
||||
case TxMessage::kUnicastResponse:
|
||||
case TxMessage::kLegacyUnicastResponse:
|
||||
shouldAppend = mUnicastAnswerPending;
|
||||
break;
|
||||
|
||||
@@ -693,6 +700,7 @@ void Core::RecordInfo::UpdateStateAfterAnswer(const TxMessage &aResponse)
|
||||
break;
|
||||
|
||||
case TxMessage::kUnicastResponse:
|
||||
case TxMessage::kLegacyUnicastResponse:
|
||||
VerifyOrExit(IsAppended());
|
||||
VerifyOrExit(mAppendSection == kAnswerSection);
|
||||
mUnicastAnswerPending = false;
|
||||
@@ -765,6 +773,7 @@ void Core::RecordInfo::MarkAsAppended(TxMessage &aTxMessage, Section aSection)
|
||||
break;
|
||||
|
||||
case TxMessage::kUnicastResponse:
|
||||
case TxMessage::kLegacyUnicastResponse:
|
||||
mAppendState = kAppendedInUnicastMsg;
|
||||
break;
|
||||
|
||||
@@ -1229,7 +1238,6 @@ template <typename EntryType> void Core::Entry::HandleTimer(EntryTimerContext &a
|
||||
case kRemoving:
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
thisAsEntryType->DetermineNextFireTime();
|
||||
|
||||
exit:
|
||||
@@ -1258,6 +1266,7 @@ void Core::Entry::AppendKeyRecordTo(TxMessage &aTxMessage, Section aSection, Nam
|
||||
{
|
||||
Message *message;
|
||||
ResourceRecord record;
|
||||
bool isLegacyUnicast = (aTxMessage.GetType() == TxMessage::kLegacyUnicastResponse);
|
||||
|
||||
VerifyOrExit(mKeyRecord.CanAppend());
|
||||
mKeyRecord.MarkAsAppended(aTxMessage, aSection);
|
||||
@@ -1270,9 +1279,9 @@ void Core::Entry::AppendKeyRecordTo(TxMessage &aTxMessage, Section aSection, Nam
|
||||
aNameAppender(*this, aTxMessage, aSection);
|
||||
|
||||
record.Init(ResourceRecord::kTypeKey);
|
||||
record.SetTtl(mKeyRecord.GetTtl());
|
||||
record.SetLength(mKeyData.GetLength());
|
||||
UpdateCacheFlushFlagIn(record, aSection);
|
||||
record.SetTtl(mKeyRecord.GetTtl(isLegacyUnicast));
|
||||
UpdateCacheFlushFlagIn(record, aSection, isLegacyUnicast);
|
||||
|
||||
SuccessOrAssert(message->Append(record));
|
||||
SuccessOrAssert(message->AppendBytes(mKeyData.GetBytes(), mKeyData.GetLength()));
|
||||
@@ -1292,10 +1301,11 @@ void Core::Entry::AppendNsecRecordTo(TxMessage &aTxMessage,
|
||||
NsecRecord nsec;
|
||||
NsecRecord::TypeBitMap bitmap;
|
||||
uint16_t offset;
|
||||
bool isLegacyUnicast = (aTxMessage.GetType() == TxMessage::kLegacyUnicastResponse);
|
||||
|
||||
nsec.Init();
|
||||
nsec.SetTtl(kNsecTtl);
|
||||
UpdateCacheFlushFlagIn(nsec, aSection);
|
||||
nsec.SetTtl(isLegacyUnicast ? kLegacyUnicastNsecTtl : kNsecTtl);
|
||||
UpdateCacheFlushFlagIn(nsec, aSection, isLegacyUnicast);
|
||||
|
||||
bitmap.Clear();
|
||||
|
||||
@@ -1606,6 +1616,7 @@ exit:
|
||||
void Core::HostEntry::AppendAddressRecordsTo(TxMessage &aTxMessage, Section aSection)
|
||||
{
|
||||
Message *message;
|
||||
bool isLegacyUnicast = (aTxMessage.GetType() == TxMessage::kLegacyUnicastResponse);
|
||||
|
||||
VerifyOrExit(mAddrRecord.CanAppend());
|
||||
mAddrRecord.MarkAsAppended(aTxMessage, aSection);
|
||||
@@ -1617,9 +1628,9 @@ void Core::HostEntry::AppendAddressRecordsTo(TxMessage &aTxMessage, Section aSec
|
||||
AaaaRecord aaaaRecord;
|
||||
|
||||
aaaaRecord.Init();
|
||||
aaaaRecord.SetTtl(mAddrRecord.GetTtl());
|
||||
aaaaRecord.SetAddress(address);
|
||||
UpdateCacheFlushFlagIn(aaaaRecord, aSection);
|
||||
aaaaRecord.SetTtl(mAddrRecord.GetTtl(isLegacyUnicast));
|
||||
UpdateCacheFlushFlagIn(aaaaRecord, aSection, isLegacyUnicast);
|
||||
|
||||
AppendNameTo(aTxMessage, aSection);
|
||||
SuccessOrAssert(message->Append(aaaaRecord));
|
||||
@@ -2383,6 +2394,7 @@ void Core::ServiceEntry::AppendSrvRecordTo(TxMessage &aTxMessage, Section aSecti
|
||||
Message *message;
|
||||
SrvRecord srv;
|
||||
uint16_t offset;
|
||||
bool isLegacyUnicast = (aTxMessage.GetType() == TxMessage::kLegacyUnicastResponse);
|
||||
|
||||
VerifyOrExit(mSrvRecord.CanAppend());
|
||||
mSrvRecord.MarkAsAppended(aTxMessage, aSection);
|
||||
@@ -2390,13 +2402,17 @@ void Core::ServiceEntry::AppendSrvRecordTo(TxMessage &aTxMessage, Section aSecti
|
||||
message = &aTxMessage.SelectMessageFor(aSection);
|
||||
|
||||
srv.Init();
|
||||
srv.SetTtl(mSrvRecord.GetTtl());
|
||||
srv.SetPriority(mPriority);
|
||||
srv.SetWeight(mWeight);
|
||||
srv.SetPort(mPort);
|
||||
UpdateCacheFlushFlagIn(srv, aSection);
|
||||
srv.SetTtl(mSrvRecord.GetTtl(isLegacyUnicast));
|
||||
UpdateCacheFlushFlagIn(srv, aSection, isLegacyUnicast);
|
||||
|
||||
// RFC6762, Section 18.14 Name Compression:
|
||||
// In legacy unicast responses generated to answer legacy queries, name
|
||||
// compression MUST NOT be performed on SRV records.
|
||||
AppendServiceNameTo(aTxMessage, aSection, /* aPerformNameCompression */ !isLegacyUnicast);
|
||||
|
||||
AppendServiceNameTo(aTxMessage, aSection);
|
||||
offset = message->GetLength();
|
||||
SuccessOrAssert(message->Append(srv));
|
||||
AppendHostNameTo(aTxMessage, aSection);
|
||||
@@ -2412,6 +2428,7 @@ void Core::ServiceEntry::AppendTxtRecordTo(TxMessage &aTxMessage, Section aSecti
|
||||
{
|
||||
Message *message;
|
||||
TxtRecord txt;
|
||||
bool isLegacyUnicast = (aTxMessage.GetType() == TxMessage::kLegacyUnicastResponse);
|
||||
|
||||
VerifyOrExit(mTxtRecord.CanAppend());
|
||||
mTxtRecord.MarkAsAppended(aTxMessage, aSection);
|
||||
@@ -2419,9 +2436,9 @@ void Core::ServiceEntry::AppendTxtRecordTo(TxMessage &aTxMessage, Section aSecti
|
||||
message = &aTxMessage.SelectMessageFor(aSection);
|
||||
|
||||
txt.Init();
|
||||
txt.SetTtl(mTxtRecord.GetTtl());
|
||||
txt.SetLength(mTxtData.GetLength());
|
||||
UpdateCacheFlushFlagIn(txt, aSection);
|
||||
txt.SetTtl(mTxtRecord.GetTtl(isLegacyUnicast));
|
||||
UpdateCacheFlushFlagIn(txt, aSection, isLegacyUnicast);
|
||||
|
||||
AppendServiceNameTo(aTxMessage, aSection);
|
||||
SuccessOrAssert(message->Append(txt));
|
||||
@@ -2442,6 +2459,7 @@ void Core::ServiceEntry::AppendPtrRecordTo(TxMessage &aTxMessage, Section aSecti
|
||||
RecordInfo &ptrRecord = (aSubType == nullptr) ? mPtrRecord : aSubType->mPtrRecord;
|
||||
PtrRecord ptr;
|
||||
uint16_t offset;
|
||||
bool isLegacyUnicast = (aTxMessage.GetType() == TxMessage::kLegacyUnicastResponse);
|
||||
|
||||
VerifyOrExit(ptrRecord.CanAppend());
|
||||
ptrRecord.MarkAsAppended(aTxMessage, aSection);
|
||||
@@ -2449,7 +2467,7 @@ void Core::ServiceEntry::AppendPtrRecordTo(TxMessage &aTxMessage, Section aSecti
|
||||
message = &aTxMessage.SelectMessageFor(aSection);
|
||||
|
||||
ptr.Init();
|
||||
ptr.SetTtl(ptrRecord.GetTtl());
|
||||
ptr.SetTtl(ptrRecord.GetTtl(isLegacyUnicast));
|
||||
|
||||
if (aSubType == nullptr)
|
||||
{
|
||||
@@ -2506,12 +2524,22 @@ void Core::ServiceEntry::AppendEntryName(Entry &aEntry, TxMessage &aTxMessage, S
|
||||
static_cast<ServiceEntry &>(aEntry).AppendServiceNameTo(aTxMessage, aSection);
|
||||
}
|
||||
|
||||
void Core::ServiceEntry::AppendServiceNameTo(TxMessage &aTxMessage, Section aSection)
|
||||
void Core::ServiceEntry::AppendServiceNameTo(TxMessage &aTxMessage, Section aSection, bool aPerformNameCompression)
|
||||
{
|
||||
AppendOutcome outcome;
|
||||
|
||||
outcome = aTxMessage.AppendLabel(aSection, mServiceInstance.AsCString(), mServiceNameOffset);
|
||||
VerifyOrExit(outcome != kAppendedFullNameAsCompressed);
|
||||
if (!aPerformNameCompression)
|
||||
{
|
||||
uint16_t compressOffset = kUnspecifiedOffset;
|
||||
|
||||
outcome = aTxMessage.AppendLabel(aSection, mServiceInstance.AsCString(), compressOffset);
|
||||
VerifyOrExit(outcome == kAppendedLabels);
|
||||
}
|
||||
else
|
||||
{
|
||||
outcome = aTxMessage.AppendLabel(aSection, mServiceInstance.AsCString(), mServiceNameOffset);
|
||||
VerifyOrExit(outcome != kAppendedFullNameAsCompressed);
|
||||
}
|
||||
|
||||
AppendServiceTypeTo(aTxMessage, aSection);
|
||||
|
||||
@@ -2775,7 +2803,14 @@ void Core::ServiceType::AppendPtrRecordTo(TxMessage &aResponse, uint16_t aServic
|
||||
message = &aResponse.SelectMessageFor(kAnswerSection);
|
||||
|
||||
ptr.Init();
|
||||
ptr.SetTtl(mServicesPtr.GetTtl());
|
||||
if (aResponse.GetType() == TxMessage::kLegacyUnicastResponse)
|
||||
{
|
||||
ptr.SetTtl(Min(Core::RecordInfo::kMaxLegacyUnicastTtl, mServicesPtr.GetTtl()));
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr.SetTtl(mServicesPtr.GetTtl());
|
||||
}
|
||||
|
||||
aResponse.AppendServicesDnssdName(kAnswerSection);
|
||||
offset = message->GetLength();
|
||||
@@ -2792,19 +2827,19 @@ exit:
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// Core::TxMessage
|
||||
|
||||
Core::TxMessage::TxMessage(Instance &aInstance, Type aType)
|
||||
Core::TxMessage::TxMessage(Instance &aInstance, Type aType, uint16_t aQueryId)
|
||||
: InstanceLocator(aInstance)
|
||||
{
|
||||
Init(aType);
|
||||
Init(aType, aQueryId);
|
||||
}
|
||||
|
||||
Core::TxMessage::TxMessage(Instance &aInstance, Type aType, const AddressInfo &aUnicastDest)
|
||||
: TxMessage(aInstance, aType)
|
||||
Core::TxMessage::TxMessage(Instance &aInstance, Type aType, const AddressInfo &aUnicastDest, uint16_t aQueryId)
|
||||
: TxMessage(aInstance, aType, aQueryId)
|
||||
{
|
||||
mUnicastDest = aUnicastDest;
|
||||
}
|
||||
|
||||
void Core::TxMessage::Init(Type aType)
|
||||
void Core::TxMessage::Init(Type aType, uint16_t aMessageId)
|
||||
{
|
||||
Header header;
|
||||
|
||||
@@ -2837,7 +2872,9 @@ void Core::TxMessage::Init(Type aType)
|
||||
break;
|
||||
case kMulticastResponse:
|
||||
case kUnicastResponse:
|
||||
case kLegacyUnicastResponse:
|
||||
header.SetType(Header::kTypeResponse);
|
||||
header.SetMessageId(aMessageId);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2864,9 +2901,9 @@ Message &Core::TxMessage::SelectMessageFor(Section aSection)
|
||||
mainSection = kQuestionSection;
|
||||
extraSection = kAnswerSection;
|
||||
break;
|
||||
|
||||
case kMulticastResponse:
|
||||
case kLegacyUnicastResponse:
|
||||
case kUnicastResponse:
|
||||
case kMulticastResponse:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3022,6 +3059,16 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Core::TxMessage::AddQuestionFrom(const Message &aMessage)
|
||||
{
|
||||
uint16_t offset = sizeof(Header);
|
||||
|
||||
IgnoreError(Name::ParseName(aMessage, offset));
|
||||
offset += sizeof(ot::Dns::Question);
|
||||
SuccessOrAssert(mMsgPtr->AppendBytesFromMessage(aMessage, sizeof(Header), offset - sizeof(Header)));
|
||||
IncrementRecordCount(kQuestionSection);
|
||||
}
|
||||
|
||||
void Core::TxMessage::SaveOffset(uint16_t &aCompressOffset, const Message &aMessage, Section aSection)
|
||||
{
|
||||
// Saves the current message offset in `aCompressOffset` for name
|
||||
@@ -3147,6 +3194,7 @@ void Core::TxMessage::Send(void)
|
||||
break;
|
||||
|
||||
case kUnicastResponse:
|
||||
case kLegacyUnicastResponse:
|
||||
otPlatMdnsSendUnicast(&GetInstance(), mMsgPtr.Release(), &mUnicastDest);
|
||||
break;
|
||||
}
|
||||
@@ -3215,6 +3263,8 @@ void Core::TxMessage::Reinit(void)
|
||||
// compress offset since the host name should not be used
|
||||
// in any other query question.
|
||||
|
||||
break;
|
||||
case kLegacyUnicastResponse:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3297,11 +3347,12 @@ Error Core::RxMessage::Init(Instance &aInstance,
|
||||
|
||||
if (aSenderAddress.mPort != kUdpPort)
|
||||
{
|
||||
if (mIsQuery)
|
||||
// Simple DNS resolver does not allow more than one question in a query message
|
||||
if (mIsQuery && header.GetQuestionCount() == 1)
|
||||
{
|
||||
// Section 6.7 Legacy Unicast
|
||||
LogInfo("We do not yet support legacy unicast message (source port not matching mDNS port)");
|
||||
ExitNow(error = kErrorNotCapable);
|
||||
mIsLegacyUnicast = true;
|
||||
mQueryId = header.GetMessageId();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3427,13 +3478,18 @@ Core::RxMessage::ProcessOutcome Core::RxMessage::ProcessQuery(bool aShouldProces
|
||||
{
|
||||
canAnswer = true;
|
||||
|
||||
if (question.mUnicastResponse)
|
||||
if (question.mUnicastResponse || mIsLegacyUnicast)
|
||||
{
|
||||
needUnicastResponse = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mIsLegacyUnicast)
|
||||
{
|
||||
shouldDelay = false;
|
||||
}
|
||||
|
||||
VerifyOrExit(canAnswer);
|
||||
|
||||
if (mTruncated && !aShouldProcessTruncated)
|
||||
@@ -3569,10 +3625,11 @@ void Core::RxMessage::AnswerQuestion(const Question &aQuestion, TimeMilli aAnswe
|
||||
|
||||
VerifyOrExit(aQuestion.mCanAnswer);
|
||||
|
||||
answerInfo.mQuestionRrType = aQuestion.mRrType;
|
||||
answerInfo.mAnswerTime = aAnswerTime;
|
||||
answerInfo.mIsProbe = aQuestion.mIsProbe;
|
||||
answerInfo.mUnicastResponse = aQuestion.mUnicastResponse;
|
||||
answerInfo.mQuestionRrType = aQuestion.mRrType;
|
||||
answerInfo.mAnswerTime = aAnswerTime;
|
||||
answerInfo.mIsProbe = aQuestion.mIsProbe;
|
||||
answerInfo.mUnicastResponse = aQuestion.mUnicastResponse;
|
||||
answerInfo.mLegacyUnicastResponse = mIsLegacyUnicast;
|
||||
|
||||
if (aQuestion.mIsForAllServicesDnssd)
|
||||
{
|
||||
@@ -3790,7 +3847,17 @@ exit:
|
||||
|
||||
void Core::RxMessage::SendUnicastResponse(const AddressInfo &aUnicastDest)
|
||||
{
|
||||
TxMessage response(GetInstance(), TxMessage::kUnicastResponse, aUnicastDest);
|
||||
TxMessage response(GetInstance(),
|
||||
mIsLegacyUnicast ? TxMessage::kLegacyUnicastResponse : TxMessage::kUnicastResponse, aUnicastDest,
|
||||
mIsLegacyUnicast ? mQueryId : 0);
|
||||
|
||||
if (mIsLegacyUnicast)
|
||||
{
|
||||
// RFC6762, section 6.7:
|
||||
// Legacy Unicast Response must repeat the question
|
||||
response.AddQuestionFrom(*mMessagePtr);
|
||||
}
|
||||
|
||||
TimeMilli now = TimerMilli::GetNow();
|
||||
|
||||
for (HostEntry &entry : Get<Core>().mHostEntries)
|
||||
|
||||
+24
-13
@@ -759,11 +759,12 @@ private:
|
||||
static constexpr uint32_t kMaxInitialQueryDelay = 120; // msec
|
||||
static constexpr uint32_t kRandomDelayReuseInterval = 2; // msec
|
||||
|
||||
static constexpr uint32_t kUnspecifiedTtl = 0;
|
||||
static constexpr uint32_t kDefaultTtl = 120;
|
||||
static constexpr uint32_t kDefaultKeyTtl = kDefaultTtl;
|
||||
static constexpr uint32_t kNsecTtl = 4500;
|
||||
static constexpr uint32_t kServicesPtrTtl = 4500;
|
||||
static constexpr uint32_t kUnspecifiedTtl = 0;
|
||||
static constexpr uint32_t kDefaultTtl = 120;
|
||||
static constexpr uint32_t kDefaultKeyTtl = kDefaultTtl;
|
||||
static constexpr uint32_t kLegacyUnicastNsecTtl = 10;
|
||||
static constexpr uint32_t kNsecTtl = 4500;
|
||||
static constexpr uint32_t kServicesPtrTtl = 4500;
|
||||
|
||||
static constexpr uint16_t kClassQuestionUnicastFlag = (1U << 15);
|
||||
static constexpr uint16_t kClassCacheFlushFlag = (1U << 15);
|
||||
@@ -858,6 +859,7 @@ private:
|
||||
TimeMilli mAnswerTime;
|
||||
bool mIsProbe;
|
||||
bool mUnicastResponse;
|
||||
bool mLegacyUnicastResponse;
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@@ -896,16 +898,19 @@ private:
|
||||
public:
|
||||
// Keeps track of record state and timings.
|
||||
|
||||
static constexpr uint32_t kMaxLegacyUnicastTtl = 10; // seconds
|
||||
|
||||
RecordInfo(void) { Clear(); }
|
||||
|
||||
bool IsPresent(void) const { return mIsPresent; }
|
||||
uint32_t GetTtl(void) const { return mTtl; }
|
||||
bool IsPresent(void) const { return mIsPresent; }
|
||||
|
||||
template <typename UintType> void UpdateProperty(UintType &aProperty, UintType aValue);
|
||||
void UpdateProperty(AddressArray &aAddrProperty, const Ip6::Address *aAddrs, uint16_t aNumAddrs);
|
||||
void UpdateProperty(Heap::String &aStringProperty, const char *aString);
|
||||
void UpdateProperty(Heap::Data &aDataProperty, const uint8_t *aData, uint16_t aLength);
|
||||
void UpdateTtl(uint32_t aTtl);
|
||||
|
||||
uint32_t GetTtl(bool aIsLegacyUnicast = false) const;
|
||||
void UpdateTtl(uint32_t aTtl);
|
||||
|
||||
void StartAnnouncing(void);
|
||||
bool ShouldAppendTo(TxMessage &aResponse, TimeMilli aNow) const;
|
||||
@@ -1162,7 +1167,7 @@ private:
|
||||
void AppendPtrRecordTo(TxMessage &aTxMessage, Section aSection, SubType *aSubType = nullptr);
|
||||
void AppendKeyRecordTo(TxMessage &aTxMessage, Section aSection);
|
||||
void AppendNsecRecordTo(TxMessage &aTxMessage, Section aSection);
|
||||
void AppendServiceNameTo(TxMessage &TxMessage, 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);
|
||||
@@ -1239,10 +1244,11 @@ private:
|
||||
kMulticastQuery,
|
||||
kMulticastResponse,
|
||||
kUnicastResponse,
|
||||
kLegacyUnicastResponse,
|
||||
};
|
||||
|
||||
TxMessage(Instance &aInstance, Type aType);
|
||||
TxMessage(Instance &aInstance, Type aType, const AddressInfo &aUnicastDest);
|
||||
TxMessage(Instance &aInstance, Type aType, uint16_t aQueryId = 0);
|
||||
TxMessage(Instance &aInstance, Type aType, const AddressInfo &aUnicastDest, uint16_t aQueryId = 0);
|
||||
Type GetType(void) const { return mType; }
|
||||
Message &SelectMessageFor(Section aSection);
|
||||
AppendOutcome AppendLabel(Section aSection, const char *aLabel, uint16_t &aCompressOffset);
|
||||
@@ -1250,6 +1256,7 @@ private:
|
||||
void AppendServiceType(Section aSection, const char *aServiceType, uint16_t &aCompressOffset);
|
||||
void AppendDomainName(Section aSection);
|
||||
void AppendServicesDnssdName(Section aSection);
|
||||
void AddQuestionFrom(const Message &aMessage);
|
||||
void IncrementRecordCount(Section aSection) { mRecordCounts.Increment(aSection); }
|
||||
void CheckSizeLimitToPrepareAgain(bool &aPrepareAgain);
|
||||
void SaveCurrentState(void);
|
||||
@@ -1259,7 +1266,7 @@ private:
|
||||
private:
|
||||
static constexpr bool kIsSingleLabel = true;
|
||||
|
||||
void Init(Type aType);
|
||||
void Init(Type aType, uint16_t aMessageId = 0);
|
||||
void Reinit(void);
|
||||
bool IsOverSizeLimit(void) const;
|
||||
AppendOutcome AppendLabels(Section aSection,
|
||||
@@ -1382,8 +1389,10 @@ private:
|
||||
AddressInfo mSenderAddress;
|
||||
RecordCounts mRecordCounts;
|
||||
uint16_t mStartOffset[kNumSections];
|
||||
uint16_t mQueryId;
|
||||
bool mIsQuery : 1;
|
||||
bool mIsUnicast : 1;
|
||||
bool mIsLegacyUnicast : 1;
|
||||
bool mTruncated : 1;
|
||||
bool mIsSelfOriginating : 1;
|
||||
};
|
||||
@@ -1984,7 +1993,9 @@ private:
|
||||
static uint32_t DetermineTtl(uint32_t aTtl, uint32_t aDefaultTtl);
|
||||
static bool NameMatch(const Heap::String &aHeapString, const char *aName);
|
||||
static bool NameMatch(const Heap::String &aFirst, const Heap::String &aSecond);
|
||||
static void UpdateCacheFlushFlagIn(ResourceRecord &aResourceRecord, Section aSection);
|
||||
static void UpdateCacheFlushFlagIn(ResourceRecord &aResourceRecord,
|
||||
Section aSection,
|
||||
bool aIsLegacyUnicast = false);
|
||||
static void UpdateRecordLengthInMessage(ResourceRecord &aRecord, Message &aMessage, uint16_t aOffset);
|
||||
static void UpdateCompressOffset(uint16_t &aOffset, uint16_t aNewOffse);
|
||||
static bool QuestionMatches(uint16_t aQuestionRrType, uint16_t aRrType);
|
||||
|
||||
+262
-31
@@ -62,17 +62,20 @@ namespace Multicast {
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// Constants
|
||||
|
||||
static constexpr uint16_t kClassQueryUnicastFlag = (1U << 15);
|
||||
static constexpr uint16_t kClassCacheFlushFlag = (1U << 15);
|
||||
static constexpr uint16_t kClassMask = 0x7fff;
|
||||
static constexpr uint16_t kStringSize = 300;
|
||||
static constexpr uint16_t kMaxDataSize = 400;
|
||||
static constexpr uint16_t kNumAnnounces = 3;
|
||||
static constexpr uint16_t kNumInitalQueries = 3;
|
||||
static constexpr uint16_t kNumRefreshQueries = 4;
|
||||
static constexpr bool kCacheFlush = true;
|
||||
static constexpr uint16_t kMdnsPort = 5353;
|
||||
static constexpr uint32_t kInfraIfIndex = 1;
|
||||
static constexpr uint16_t kClassQueryUnicastFlag = (1U << 15);
|
||||
static constexpr uint16_t kClassCacheFlushFlag = (1U << 15);
|
||||
static constexpr uint16_t kClassMask = 0x7fff;
|
||||
static constexpr uint16_t kStringSize = 300;
|
||||
static constexpr uint16_t kMaxDataSize = 400;
|
||||
static constexpr uint16_t kNumAnnounces = 3;
|
||||
static constexpr uint16_t kNumInitalQueries = 3;
|
||||
static constexpr uint16_t kNumRefreshQueries = 4;
|
||||
static constexpr bool kCacheFlush = true;
|
||||
static constexpr uint16_t kMdnsPort = 5353;
|
||||
static constexpr uint16_t kEphemeralPort = 49152;
|
||||
static constexpr uint16_t kLegacyUnicastMessageId = 1;
|
||||
static constexpr uint16_t kMaxLegacyUnicastTtl = 10;
|
||||
static constexpr uint32_t kInfraIfIndex = 1;
|
||||
|
||||
static const char kDeviceIp6Address[] = "fd01::1";
|
||||
|
||||
@@ -209,6 +212,7 @@ enum TtlCheckMode : uint8_t
|
||||
{
|
||||
kZeroTtl,
|
||||
kNonZeroTtl,
|
||||
kLegacyUnicastTtl,
|
||||
};
|
||||
|
||||
enum Section : uint8_t
|
||||
@@ -372,6 +376,9 @@ struct DnsRecord : public Allocatable<DnsRecord>, public LinkedListEntry<DnsReco
|
||||
|
||||
VerifyOrExit(mTtl > 0);
|
||||
break;
|
||||
case kLegacyUnicastTtl:
|
||||
VerifyOrQuit(mTtl <= kMaxLegacyUnicastTtl);
|
||||
break;
|
||||
}
|
||||
|
||||
matches = true;
|
||||
@@ -571,6 +578,7 @@ enum DnsMessageType : uint8_t
|
||||
kMulticastQuery,
|
||||
kMulticastResponse,
|
||||
kUnicastResponse,
|
||||
kLegacyUnicastResponse,
|
||||
};
|
||||
|
||||
struct DnsMessage : public Allocatable<DnsMessage>, public LinkedListEntry<DnsMessage>
|
||||
@@ -682,9 +690,15 @@ struct DnsMessage : public Allocatable<DnsMessage>, public LinkedListEntry<DnsMe
|
||||
VerifyOrQuit(mUnicastDest.mPort == kMdnsPort);
|
||||
VerifyOrQuit(mUnicastDest.GetAddress() == ip6Address);
|
||||
}
|
||||
|
||||
if (aType == kLegacyUnicastResponse)
|
||||
{
|
||||
VerifyOrQuit(mHeader.GetMessageId() == kLegacyUnicastMessageId);
|
||||
VerifyOrQuit(mUnicastDest.mPort == kEphemeralPort);
|
||||
}
|
||||
}
|
||||
|
||||
static void DetemineFullNameForKey(const Core::Key &aKey, DnsNameString &aFullName)
|
||||
static void DetermineFullNameForKey(const Core::Key &aKey, DnsNameString &aFullName)
|
||||
{
|
||||
if (aKey.mServiceType != nullptr)
|
||||
{
|
||||
@@ -696,6 +710,22 @@ struct DnsMessage : public Allocatable<DnsMessage>, public LinkedListEntry<DnsMe
|
||||
}
|
||||
}
|
||||
|
||||
static TtlCheckMode DetermineTtlCheckMode(DnsMessageType aMessageType, bool aIsGoodBye)
|
||||
{
|
||||
TtlCheckMode ttlCheck;
|
||||
|
||||
if (aMessageType == kLegacyUnicastResponse)
|
||||
{
|
||||
ttlCheck = kLegacyUnicastTtl;
|
||||
}
|
||||
else
|
||||
{
|
||||
ttlCheck = aIsGoodBye ? kZeroTtl : kNonZeroTtl;
|
||||
}
|
||||
|
||||
return ttlCheck;
|
||||
}
|
||||
|
||||
void ValidateAsProbeFor(const Core::Host &aHost, bool aUnicastResponse) const
|
||||
{
|
||||
DnsNameString fullName;
|
||||
@@ -735,7 +765,7 @@ struct DnsMessage : public Allocatable<DnsMessage>, public LinkedListEntry<DnsMe
|
||||
VerifyOrQuit(mHeader.GetType() == Header::kTypeQuery);
|
||||
VerifyOrQuit(!mHeader.IsTruncationFlagSet());
|
||||
|
||||
DetemineFullNameForKey(aKey, fullName);
|
||||
DetermineFullNameForKey(aKey, fullName);
|
||||
|
||||
VerifyOrQuit(mQuestions.Contains(fullName, aUnicastResponse));
|
||||
VerifyOrQuit(mAuthRecords.ContainsKey(fullName, Data(aKey.mKeyData, aKey.mKeyDataLength), !kCacheFlush,
|
||||
@@ -745,6 +775,11 @@ struct DnsMessage : public Allocatable<DnsMessage>, public LinkedListEntry<DnsMe
|
||||
void Validate(const Core::Host &aHost, Section aSection, GoodBye aIsGoodBye = kNotGoodBye) const
|
||||
{
|
||||
DnsNameString fullName;
|
||||
TtlCheckMode ttlCheck;
|
||||
|
||||
bool cacheFlushSet = (mType == kLegacyUnicastResponse) ? !kCacheFlush : kCacheFlush;
|
||||
|
||||
ttlCheck = DetermineTtlCheckMode(mType, aIsGoodBye);
|
||||
|
||||
VerifyOrQuit(mHeader.GetType() == Header::kTypeResponse);
|
||||
|
||||
@@ -752,8 +787,8 @@ struct DnsMessage : public Allocatable<DnsMessage>, public LinkedListEntry<DnsMe
|
||||
|
||||
for (uint16_t index = 0; index < aHost.mAddressesLength; index++)
|
||||
{
|
||||
VerifyOrQuit(RecordsFor(aSection).ContainsAaaa(fullName, AsCoreType(&aHost.mAddresses[index]), kCacheFlush,
|
||||
aIsGoodBye ? kZeroTtl : kNonZeroTtl, aHost.mTtl));
|
||||
VerifyOrQuit(RecordsFor(aSection).ContainsAaaa(fullName, AsCoreType(&aHost.mAddresses[index]),
|
||||
cacheFlushSet, ttlCheck, aHost.mTtl));
|
||||
}
|
||||
|
||||
if (!aIsGoodBye && (aSection == kInAnswerSection))
|
||||
@@ -769,7 +804,11 @@ struct DnsMessage : public Allocatable<DnsMessage>, public LinkedListEntry<DnsMe
|
||||
{
|
||||
DnsNameString serviceName;
|
||||
DnsNameString serviceType;
|
||||
bool checkNsec = false;
|
||||
TtlCheckMode ttlCheck;
|
||||
bool checkNsec = false;
|
||||
bool cacheFlushSet = (mType == kLegacyUnicastResponse) ? !kCacheFlush : kCacheFlush;
|
||||
|
||||
ttlCheck = DetermineTtlCheckMode(mType, aIsGoodBye);
|
||||
|
||||
VerifyOrQuit(mHeader.GetType() == Header::kTypeResponse);
|
||||
|
||||
@@ -778,22 +817,23 @@ struct DnsMessage : public Allocatable<DnsMessage>, public LinkedListEntry<DnsMe
|
||||
|
||||
if (aCheckFlags & kCheckSrv)
|
||||
{
|
||||
VerifyOrQuit(RecordsFor(aSection).ContainsSrv(serviceName, aService, kCacheFlush,
|
||||
aIsGoodBye ? kZeroTtl : kNonZeroTtl, aService.mTtl));
|
||||
VerifyOrQuit(
|
||||
RecordsFor(aSection).ContainsSrv(serviceName, aService, cacheFlushSet, ttlCheck, aService.mTtl));
|
||||
|
||||
checkNsec = true;
|
||||
}
|
||||
|
||||
if (aCheckFlags & kCheckTxt)
|
||||
{
|
||||
VerifyOrQuit(RecordsFor(aSection).ContainsTxt(serviceName, aService, kCacheFlush,
|
||||
aIsGoodBye ? kZeroTtl : kNonZeroTtl, aService.mTtl));
|
||||
VerifyOrQuit(
|
||||
RecordsFor(aSection).ContainsTxt(serviceName, aService, cacheFlushSet, ttlCheck, aService.mTtl));
|
||||
|
||||
checkNsec = true;
|
||||
}
|
||||
|
||||
if (aCheckFlags & kCheckPtr)
|
||||
{
|
||||
VerifyOrQuit(RecordsFor(aSection).ContainsPtr(serviceType, serviceName, aIsGoodBye ? kZeroTtl : kNonZeroTtl,
|
||||
aService.mTtl));
|
||||
VerifyOrQuit(RecordsFor(aSection).ContainsPtr(serviceType, serviceName, ttlCheck, aService.mTtl));
|
||||
}
|
||||
|
||||
if (aCheckFlags & kCheckServicesPtr)
|
||||
@@ -811,12 +851,17 @@ struct DnsMessage : public Allocatable<DnsMessage>, public LinkedListEntry<DnsMe
|
||||
void Validate(const Core::Key &aKey, Section aSection, GoodBye aIsGoodBye = kNotGoodBye) const
|
||||
{
|
||||
DnsNameString fullName;
|
||||
TtlCheckMode ttlCheck;
|
||||
bool cacheFlushSet = (mType == kLegacyUnicastResponse) ? !kCacheFlush : kCacheFlush;
|
||||
|
||||
VerifyOrQuit(mHeader.GetType() == Header::kTypeResponse);
|
||||
|
||||
DetemineFullNameForKey(aKey, fullName);
|
||||
VerifyOrQuit(RecordsFor(aSection).ContainsKey(fullName, Data(aKey.mKeyData, aKey.mKeyDataLength), kCacheFlush,
|
||||
aIsGoodBye ? kZeroTtl : kNonZeroTtl, aKey.mTtl));
|
||||
DetermineFullNameForKey(aKey, fullName);
|
||||
|
||||
ttlCheck = DetermineTtlCheckMode(mType, aIsGoodBye);
|
||||
|
||||
VerifyOrQuit(RecordsFor(aSection).ContainsKey(fullName, Data(aKey.mKeyData, aKey.mKeyDataLength), cacheFlushSet,
|
||||
ttlCheck, aKey.mTtl));
|
||||
|
||||
if (!aIsGoodBye && (aSection == kInAnswerSection))
|
||||
{
|
||||
@@ -1035,7 +1080,7 @@ static void ParseMessage(const Message &aMessage, const Core::AddressInfo *aUnic
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->mType = kUnicastResponse;
|
||||
msg->mType = (aUnicastDest->mPort == kEphemeralPort) ? kLegacyUnicastResponse : kUnicastResponse;
|
||||
msg->mUnicastDest = *aUnicastDest;
|
||||
}
|
||||
}
|
||||
@@ -1045,8 +1090,9 @@ static void ParseMessage(const Message &aMessage, const Core::AddressInfo *aUnic
|
||||
|
||||
static void SendQuery(const char *aName,
|
||||
uint16_t aRecordType,
|
||||
uint16_t aRecordClass = ResourceRecord::kClassInternet,
|
||||
bool aTruncated = false)
|
||||
uint16_t aRecordClass = ResourceRecord::kClassInternet,
|
||||
bool aTruncated = false,
|
||||
bool aLegacyUnicastQuery = false)
|
||||
{
|
||||
Message *message;
|
||||
Header header;
|
||||
@@ -1059,6 +1105,11 @@ static void SendQuery(const char *aName,
|
||||
header.SetType(Header::kTypeQuery);
|
||||
header.SetQuestionCount(1);
|
||||
|
||||
if (aLegacyUnicastQuery)
|
||||
{
|
||||
header.SetMessageId(kLegacyUnicastMessageId);
|
||||
}
|
||||
|
||||
if (aTruncated)
|
||||
{
|
||||
header.SetTruncationFlag();
|
||||
@@ -1069,7 +1120,7 @@ static void SendQuery(const char *aName,
|
||||
SuccessOrQuit(message->Append(Question(aRecordType, aRecordClass)));
|
||||
|
||||
SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
|
||||
senderAddrInfo.mPort = kMdnsPort;
|
||||
senderAddrInfo.mPort = aLegacyUnicastQuery ? kEphemeralPort : kMdnsPort;
|
||||
senderAddrInfo.mInfraIfIndex = 0;
|
||||
|
||||
Log("Sending query for %s %s", aName, RecordTypeToString(aRecordType));
|
||||
@@ -1077,7 +1128,11 @@ static void SendQuery(const char *aName,
|
||||
otPlatMdnsHandleReceive(sInstance, message, /* aIsUnicast */ false, &senderAddrInfo);
|
||||
}
|
||||
|
||||
static void SendQueryForTwo(const char *aName1, uint16_t aRecordType1, const char *aName2, uint16_t aRecordType2)
|
||||
static void SendQueryForTwo(const char *aName1,
|
||||
uint16_t aRecordType1,
|
||||
const char *aName2,
|
||||
uint16_t aRecordType2,
|
||||
bool aIsLegacyUnicast = false)
|
||||
{
|
||||
// Send query with two questions.
|
||||
|
||||
@@ -1099,7 +1154,7 @@ static void SendQueryForTwo(const char *aName1, uint16_t aRecordType1, const cha
|
||||
SuccessOrQuit(message->Append(Question(aRecordType2, ResourceRecord::kClassInternet)));
|
||||
|
||||
SuccessOrQuit(AsCoreType(&senderAddrInfo.mAddress).FromString(kDeviceIp6Address));
|
||||
senderAddrInfo.mPort = kMdnsPort;
|
||||
senderAddrInfo.mPort = aIsLegacyUnicast ? kEphemeralPort : kMdnsPort;
|
||||
senderAddrInfo.mInfraIfIndex = 0;
|
||||
|
||||
Log("Sending query for %s %s and %s %s", aName1, RecordTypeToString(aRecordType1), aName2,
|
||||
@@ -6877,6 +6932,181 @@ void TestPassiveCache(void)
|
||||
testFreeInstance(sInstance);
|
||||
}
|
||||
|
||||
void TestLegacyUnicastResponse(void)
|
||||
{
|
||||
Core *mdns = InitTest();
|
||||
Core::Host host;
|
||||
Core::Service service;
|
||||
const DnsMessage *dnsMsg;
|
||||
uint16_t heapAllocations;
|
||||
DnsNameString fullServiceName;
|
||||
DnsNameString fullServiceType;
|
||||
DnsNameString hostFullName;
|
||||
Ip6::Address hostAddresses[2];
|
||||
|
||||
Log("-------------------------------------------------------------------------------------------");
|
||||
Log("TestLegacyUnicastResponse");
|
||||
|
||||
AdvanceTime(1);
|
||||
|
||||
heapAllocations = sHeapAllocatedPtrs.GetLength();
|
||||
SuccessOrQuit(mdns->SetEnabled(true, kInfraIfIndex));
|
||||
|
||||
SuccessOrQuit(hostAddresses[0].FromString("fd00::1:aaaa"));
|
||||
SuccessOrQuit(hostAddresses[1].FromString("fd00::1:bbbb"));
|
||||
host.mHostName = "host";
|
||||
host.mAddresses = hostAddresses;
|
||||
host.mAddressesLength = 2;
|
||||
host.mTtl = 1500;
|
||||
hostFullName.Append("%s.local.", host.mHostName);
|
||||
|
||||
service.mHostName = host.mHostName;
|
||||
service.mServiceInstance = "myservice";
|
||||
service.mServiceType = "_srv._udp";
|
||||
service.mSubTypeLabels = nullptr;
|
||||
service.mSubTypeLabelsLength = 0;
|
||||
service.mTxtData = kTxtData1;
|
||||
service.mTxtDataLength = sizeof(kTxtData1);
|
||||
service.mPort = 1234;
|
||||
service.mPriority = 1;
|
||||
service.mWeight = 2;
|
||||
service.mTtl = 1000;
|
||||
|
||||
fullServiceName.Append("%s.%s.local.", service.mServiceInstance, service.mServiceType);
|
||||
fullServiceType.Append("%s.local.", service.mServiceType);
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
|
||||
sDnsMessages.Clear();
|
||||
|
||||
for (RegCallback ®Callbck : sRegCallbacks)
|
||||
{
|
||||
regCallbck.Reset();
|
||||
}
|
||||
|
||||
SuccessOrQuit(mdns->RegisterHost(host, 0, HandleSuccessCallback));
|
||||
SuccessOrQuit(mdns->RegisterService(service, 1, HandleSuccessCallback));
|
||||
|
||||
AdvanceTime(10 * 1000);
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
Log("Send a query with two questions (SRV for service1 and AAAA for host). Validate that no response is sent");
|
||||
|
||||
AdvanceTime(2000);
|
||||
|
||||
sDnsMessages.Clear();
|
||||
SendQueryForTwo(fullServiceName.AsCString(), ResourceRecord::kTypeSrv, hostFullName.AsCString(),
|
||||
ResourceRecord::kTypeAaaa, /* aIsLegacyUnicast */ true);
|
||||
|
||||
AdvanceTime(200);
|
||||
|
||||
dnsMsg = sDnsMessages.GetHead();
|
||||
VerifyOrQuit(dnsMsg == nullptr);
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
Log("Send a query for SRV record and validate the response");
|
||||
|
||||
AdvanceTime(2000);
|
||||
|
||||
sDnsMessages.Clear();
|
||||
SendQuery(fullServiceName.AsCString(), ResourceRecord::kTypeSrv, ResourceRecord::kClassInternet,
|
||||
/* aTruncated */ false,
|
||||
/* aLegacyUnicastQuery */ true);
|
||||
|
||||
AdvanceTime(1000);
|
||||
|
||||
dnsMsg = sDnsMessages.GetHead();
|
||||
VerifyOrQuit(dnsMsg != nullptr);
|
||||
dnsMsg->ValidateHeader(kLegacyUnicastResponse, /* Q */ 1, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 3);
|
||||
dnsMsg->Validate(service, kInAnswerSection, kCheckSrv);
|
||||
dnsMsg->Validate(host, kInAdditionalSection);
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
Log("Send a query for TXT record and validate the response");
|
||||
|
||||
AdvanceTime(2000);
|
||||
|
||||
sDnsMessages.Clear();
|
||||
SendQuery(fullServiceName.AsCString(), ResourceRecord::kTypeTxt, ResourceRecord::kClassInternet,
|
||||
/* aTruncated */ false,
|
||||
/* aLegacyUnicastQuery */ true);
|
||||
|
||||
AdvanceTime(1000);
|
||||
|
||||
dnsMsg = sDnsMessages.GetHead();
|
||||
VerifyOrQuit(dnsMsg != nullptr);
|
||||
dnsMsg->ValidateHeader(kLegacyUnicastResponse, /* Q */ 1, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 1);
|
||||
dnsMsg->Validate(service, kInAnswerSection, kCheckTxt);
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
Log("Send a query for ANY record and validate the response");
|
||||
|
||||
AdvanceTime(2000);
|
||||
|
||||
sDnsMessages.Clear();
|
||||
SendQuery(fullServiceName.AsCString(), ResourceRecord::kTypeAny, ResourceRecord::kClassInternet,
|
||||
/* aTruncated */ false,
|
||||
/* aLegacyUnicastQuery */ true);
|
||||
|
||||
AdvanceTime(1000);
|
||||
|
||||
dnsMsg = sDnsMessages.GetHead();
|
||||
VerifyOrQuit(dnsMsg != nullptr);
|
||||
dnsMsg->ValidateHeader(kLegacyUnicastResponse, /* Q */ 1, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 3);
|
||||
dnsMsg->Validate(service, kInAnswerSection, kCheckSrv | kCheckTxt);
|
||||
dnsMsg->Validate(host, kInAdditionalSection);
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
Log("Send a query for PTR record for service type and validate the response");
|
||||
|
||||
AdvanceTime(2000);
|
||||
|
||||
sDnsMessages.Clear();
|
||||
SendQuery(fullServiceType.AsCString(), ResourceRecord::kTypePtr, ResourceRecord::kClassInternet,
|
||||
/* aTruncated */ false,
|
||||
/* aLegacyUnicastQuery */ true);
|
||||
|
||||
AdvanceTime(1000);
|
||||
|
||||
dnsMsg = sDnsMessages.GetHead();
|
||||
VerifyOrQuit(dnsMsg != nullptr);
|
||||
dnsMsg->ValidateHeader(kLegacyUnicastResponse, /* Q */ 1, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 4);
|
||||
dnsMsg->Validate(service, kInAnswerSection, kCheckPtr);
|
||||
dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt);
|
||||
dnsMsg->Validate(host, kInAdditionalSection);
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
Log("Send a query for non-existing record and validate the response with NSEC");
|
||||
|
||||
AdvanceTime(2000);
|
||||
|
||||
sDnsMessages.Clear();
|
||||
SendQuery(hostFullName.AsCString(), ResourceRecord::kTypeA, ResourceRecord::kClassInternet, /* aTruncated */ false,
|
||||
/* aLegacyUnicastQuery */ true);
|
||||
|
||||
AdvanceTime(1000);
|
||||
|
||||
dnsMsg = sDnsMessages.GetHead();
|
||||
VerifyOrQuit(dnsMsg != nullptr);
|
||||
dnsMsg->ValidateHeader(kLegacyUnicastResponse, /* Q */ 1, /* Ans */ 0, /* Auth */ 0, /* Addnl */ 1);
|
||||
VerifyOrQuit(dnsMsg->mAdditionalRecords.ContainsNsec(hostFullName, ResourceRecord::kTypeAaaa));
|
||||
|
||||
Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
|
||||
sDnsMessages.Clear();
|
||||
|
||||
SuccessOrQuit(mdns->UnregisterHost(host));
|
||||
|
||||
AdvanceTime(15000);
|
||||
|
||||
SuccessOrQuit(mdns->SetEnabled(false, kInfraIfIndex));
|
||||
VerifyOrQuit(sHeapAllocatedPtrs.GetLength() <= heapAllocations);
|
||||
|
||||
Log("End of test");
|
||||
|
||||
testFreeInstance(sInstance);
|
||||
}
|
||||
|
||||
} // namespace Multicast
|
||||
} // namespace Dns
|
||||
} // namespace ot
|
||||
@@ -6904,6 +7134,7 @@ int main(void)
|
||||
ot::Dns::Multicast::TestTxtResolver();
|
||||
ot::Dns::Multicast::TestIp6AddrResolver();
|
||||
ot::Dns::Multicast::TestPassiveCache();
|
||||
ot::Dns::Multicast::TestLegacyUnicastResponse();
|
||||
|
||||
printf("All tests passed\n");
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user