From 153e2567cd379dc6b21de18f1631544f6e157ffd Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 21 May 2024 13:24:45 -0700 Subject: [PATCH] [mdns] include additional records along with sub-type PTR answer (#10276) This commit updates the native mDNS implementation to include additional records (SRV, TXT, and AAAA for host) when answering sub-type PTR (browse) queries, the same way it is included for base PTR queries. The unit test `test_mdns` is also updated to verify and expect this behavior accordingly. --- src/core/net/mdns.cpp | 32 ++++++++++++++++++++++---------- tests/unit/test_mdns.cpp | 19 ++++++++++++++----- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/core/net/mdns.cpp b/src/core/net/mdns.cpp index e06b0a787..df0a61fdd 100644 --- a/src/core/net/mdns.cpp +++ b/src/core/net/mdns.cpp @@ -2079,15 +2079,17 @@ void Core::ServiceEntry::PrepareResponse(TxMessage &aResponse, TimeMilli aNow) void Core::ServiceEntry::PrepareResponseRecords(TxMessage &aResponse, TimeMilli aNow) { - bool appendNsec = false; - HostEntry *hostEntry = nullptr; + bool appendNsec = false; + bool appendAdditionalRecordsForPtr = false; + HostEntry *hostEntry = nullptr; DiscoverOffsetsAndHost(hostEntry); // We determine records to include in Additional Data section // per RFC 6763 section 12: // - // - For base PTR, we include SRV, TXT, and host addresses. + // - For PTR (base or sub-type), we include SRV, TXT, and host + // addresses. // - For SRV, we include host addresses only (TXT record not // recommended). // @@ -2104,13 +2106,7 @@ void Core::ServiceEntry::PrepareResponseRecords(TxMessage &aResponse, TimeMilli if (mPtrRecord.GetTtl() > 0) { - mSrvRecord.MarkToAppendInAdditionalData(); - mTxtRecord.MarkToAppendInAdditionalData(); - - if (hostEntry != nullptr) - { - hostEntry->mAddrRecord.MarkToAppendInAdditionalData(); - } + appendAdditionalRecordsForPtr = true; } } @@ -2119,6 +2115,22 @@ void Core::ServiceEntry::PrepareResponseRecords(TxMessage &aResponse, TimeMilli if (subType.mPtrRecord.ShouldAppendTo(aResponse, aNow)) { AppendPtrRecordTo(aResponse, kAnswerSection, &subType); + + if (subType.mPtrRecord.GetTtl() > 0) + { + appendAdditionalRecordsForPtr = true; + } + } + } + + if (appendAdditionalRecordsForPtr) + { + mSrvRecord.MarkToAppendInAdditionalData(); + mTxtRecord.MarkToAppendInAdditionalData(); + + if (hostEntry != nullptr) + { + hostEntry->mAddrRecord.MarkToAppendInAdditionalData(); } } diff --git a/tests/unit/test_mdns.cpp b/tests/unit/test_mdns.cpp index aa927ea29..1dd114e96 100644 --- a/tests/unit/test_mdns.cpp +++ b/tests/unit/test_mdns.cpp @@ -2728,8 +2728,9 @@ void TestServiceSubTypeReg(void) dnsMsg = sDnsMessages.GetHead(); VerifyOrQuit(dnsMsg != nullptr); - dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0); + dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 2); dnsMsg->ValidateSubType(service.mSubTypeLabels[index], service); + dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt); } Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); @@ -2762,8 +2763,9 @@ void TestServiceSubTypeReg(void) VerifyOrQuit(!sDnsMessages.IsEmpty()); dnsMsg = sDnsMessages.GetHead(); - dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0); + dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 2); dnsMsg->ValidateSubType(service.mSubTypeLabels[3], service); + dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt); VerifyOrQuit(dnsMsg->GetNext() == nullptr); sDnsMessages.Clear(); } @@ -2842,11 +2844,12 @@ void TestServiceSubTypeReg(void) VerifyOrQuit(!sDnsMessages.IsEmpty()); dnsMsg = sDnsMessages.GetHead(); - dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 3, /* Auth */ 0, /* Addnl */ 0); + dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 3, /* Auth */ 0, /* Addnl */ 2); dnsMsg->ValidateSubType(kSubTypes1[3], service, kGoodBye); dnsMsg->ValidateSubType(kSubTypes2[1], service); dnsMsg->ValidateSubType(kSubTypes2[3], service); + dnsMsg->Validate(service, kInAdditionalSection, kCheckSrv | kCheckTxt); VerifyOrQuit(dnsMsg->GetNext() == nullptr); sDnsMessages.Clear(); @@ -3513,10 +3516,14 @@ void TestQuery(void) VerifyOrQuit(dnsMsg != nullptr); VerifyOrQuit(dnsMsg->GetNext() == nullptr); - dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 0); + dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 2, /* Auth */ 0, /* Addnl */ 9); dnsMsg->ValidateSubType("_s", service1); dnsMsg->ValidateSubType("_s", service3); + dnsMsg->Validate(service1, kInAdditionalSection, kCheckSrv | kCheckTxt); + dnsMsg->Validate(service3, kInAdditionalSection, kCheckSrv | kCheckTxt); + dnsMsg->Validate(host1, kInAdditionalSection); + dnsMsg->Validate(host2, kInAdditionalSection); // Send same query again and make sure it is ignored (rate limit). @@ -3540,8 +3547,10 @@ void TestQuery(void) VerifyOrQuit(dnsMsg != nullptr); VerifyOrQuit(dnsMsg->GetNext() == nullptr); - dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 0); + dnsMsg->ValidateHeader(kMulticastResponse, /* Q */ 0, /* Ans */ 1, /* Auth */ 0, /* Addnl */ 5); dnsMsg->ValidateSubType("_r", service1); + dnsMsg->Validate(service1, kInAdditionalSection, kCheckSrv | kCheckTxt); + dnsMsg->Validate(host1, kInAdditionalSection); Log("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); Log("Validate that query with other `class` is ignored");