Skip to content

Commit 3e7528e

Browse files
authored
[dns-client] use DecompressRecordData() for broader record type support (openthread#11412)
This commit updates the DNS client to use `DecompressRecordData()` helper method when processing `QueryRecord()` responses for arbitrary record types. This enables decompression of embedded DNS names within the received record data for a wider range of record types. In particular, name decompression is now supported for PTR, CNAME, DNAME, NS, SRV, SOA, MX, RP, AFSDB, RT, PX, KX, and NSEC records.
1 parent b017644 commit 3e7528e

3 files changed

Lines changed: 15 additions & 47 deletions

File tree

include/openthread/dns_client.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -760,11 +760,11 @@ otError otDnsRecordResponseGetQueryName(const otDnsRecordResponse *aResponse,
760760
* - The data is copied into `mDataBuffer` (if not `NULL`) up to its capacity specified by `mDataBufferSize`.
761761
* - `mDataBufferSize` is then updated to reflect the number of bytes actually written into `mDataBuffer`.
762762
*
763-
* If the retrieved record type is PTR (12), CNAME (5), DNAME (39), NS (2), or SRV (33), the record data in the
764-
* received response contains a DNS name which may use DNS name compression. For these specific record types, the
765-
* record data is first decompressed such that it contains the full uncompressed DNS name. This decompressed data is
766-
* then provided in `mDataBuffer`, and `mRecordDataLength` will indicate the length of this decompressed data. For all
767-
* other record types, the record data is read and provided as it appears in the received response message.
763+
* If the retrieved record type is NS, CNAME, SOA, PTR, MX, RP, AFSDB, RT, PX, SRV, KX, DNAME, or NSEC, the record
764+
* data in the received response contains a DNS name which may use DNS name compression. For these specific record
765+
* types, the record data is first decompressed such that it contains the full uncompressed DNS name. This decompressed
766+
* data is then provided in `mDataBuffer`, and `mRecordDataLength` will indicate the length of this decompressed data.
767+
* For all other record types, the record data is read and provided as it appears in the received response message.
768768
*
769769
* @param[in] aResponse A pointer to the response.
770770
* @param[in] aIndex The record index to retrieve.
@@ -774,7 +774,7 @@ otError otDnsRecordResponseGetQueryName(const otDnsRecordResponse *aResponse,
774774
* @retval OT_ERROR_NOT_FOUND No record in @p aResponse at @p aIndex.
775775
* @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse.
776776
* @retval OT_ERROR_NO_BUFS The record name does not fit in the provided `mNameBufferSize` in @p aRecordInfo, or
777-
* failed to allocate buffer to decompress a compressed DNS name (PTR, SRV, CNAME).
777+
* failed to allocate buffer to decompress a compressed DNS name.
778778
*/
779779
otError otDnsRecordResponseGetRecordInfo(const otDnsRecordResponse *aResponse,
780780
uint16_t aIndex,

include/openthread/instance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ extern "C" {
5252
*
5353
* @note This number versions both OpenThread platform and user APIs.
5454
*/
55-
#define OPENTHREAD_API_VERSION (501)
55+
#define OPENTHREAD_API_VERSION (502)
5656

5757
/**
5858
* @addtogroup api-instance

src/core/net/dns_client.cpp

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -378,10 +378,10 @@ Error Client::Response::ReadTxtRecord(Section aSection, const Name &aName, Servi
378378

379379
Error Client::Response::ReadRecordInfo(uint16_t aIndex, RecordInfo &aRecordInfo) const
380380
{
381-
Error error;
382-
uint16_t offset;
383-
ResourceRecord record;
384-
Message *decompressedData = nullptr;
381+
Error error;
382+
uint16_t offset;
383+
ResourceRecord record;
384+
OwnedPtr<Message> decompressedData;
385385

386386
if (aIndex < mAnswerRecordCount)
387387
{
@@ -406,43 +406,12 @@ Error Client::Response::ReadRecordInfo(uint16_t aIndex, RecordInfo &aRecordInfo)
406406
SuccessOrExit(error = Name::ReadName(*mMessage, offset, aRecordInfo.mNameBuffer, aRecordInfo.mNameBufferSize));
407407

408408
SuccessOrExit(error = mMessage->Read(offset, record));
409-
VerifyOrExit(offset + record.GetSize() <= mMessage->GetLength(), error = kErrorParse);
410-
offset += sizeof(record);
411409

412-
aRecordInfo.mRecordType = record.GetType();
413-
aRecordInfo.mTtl = record.GetTtl();
414-
415-
// We may need to translate the record data for PTR, CNAME, DNAME, NS
416-
// and SRV record since the data format contains a DNS name which
417-
// may use compression.
418-
419-
switch (record.GetType())
420-
{
421-
case ResourceRecord::kTypePtr:
422-
case ResourceRecord::kTypeCname:
423-
case ResourceRecord::kTypeDname:
424-
case ResourceRecord::kTypeNs:
425-
case ResourceRecord::kTypeSrv:
426-
decompressedData = mMessage->Get<MessagePool>().Allocate(Message::kTypeOther);
427-
VerifyOrExit(decompressedData != nullptr, error = kErrorNoBufs);
428-
429-
if (record.GetType() == ResourceRecord::kTypeSrv)
430-
{
431-
uint16_t srvMinLength = sizeof(SrvRecord) - sizeof(ResourceRecord);
432-
433-
VerifyOrExit(record.GetLength() > srvMinLength, error = kErrorParse);
434-
SuccessOrExit(error = decompressedData->AppendBytesFromMessage(*mMessage, offset, srvMinLength));
435-
offset += srvMinLength;
436-
}
437-
438-
SuccessOrExit(error = Name(*mMessage, offset).AppendTo(*decompressedData));
439-
break;
440-
441-
default:
442-
break;
443-
}
410+
SuccessOrExit(error = ResourceRecord::DecompressRecordData(*mMessage, offset, decompressedData));
444411

412+
aRecordInfo.mRecordType = record.GetType();
445413
aRecordInfo.mRecordLength = (decompressedData != nullptr) ? decompressedData->GetLength() : record.GetLength();
414+
aRecordInfo.mTtl = record.GetTtl();
446415

447416
if (aRecordInfo.mDataBuffer == nullptr)
448417
{
@@ -458,11 +427,10 @@ Error Client::Response::ReadRecordInfo(uint16_t aIndex, RecordInfo &aRecordInfo)
458427
}
459428
else
460429
{
461-
mMessage->ReadBytes(offset, aRecordInfo.mDataBuffer, aRecordInfo.mDataBufferSize);
430+
mMessage->ReadBytes(offset + sizeof(ResourceRecord), aRecordInfo.mDataBuffer, aRecordInfo.mDataBufferSize);
462431
}
463432

464433
exit:
465-
FreeMessage(decompressedData);
466434
return error;
467435
}
468436

0 commit comments

Comments
 (0)