mirror of
https://github.com/espressif/openthread.git
synced 2025-05-17 15:26:16 +08:00
[dns-client] use DecompressRecordData()
for broader record type support (#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.
This commit is contained in:

committed by
GitHub

parent
b0176443cc
commit
3e7528e4e9
@ -760,11 +760,11 @@ otError otDnsRecordResponseGetQueryName(const otDnsRecordResponse *aResponse,
|
|||||||
* - The data is copied into `mDataBuffer` (if not `NULL`) up to its capacity specified by `mDataBufferSize`.
|
* - The data is copied into `mDataBuffer` (if not `NULL`) up to its capacity specified by `mDataBufferSize`.
|
||||||
* - `mDataBufferSize` is then updated to reflect the number of bytes actually written into `mDataBuffer`.
|
* - `mDataBufferSize` is then updated to reflect the number of bytes actually written into `mDataBuffer`.
|
||||||
*
|
*
|
||||||
* If the retrieved record type is PTR (12), CNAME (5), DNAME (39), NS (2), or SRV (33), the record data in the
|
* If the retrieved record type is NS, CNAME, SOA, PTR, MX, RP, AFSDB, RT, PX, SRV, KX, DNAME, or NSEC, the record
|
||||||
* received response contains a DNS name which may use DNS name compression. For these specific record types, the
|
* data in the received response contains a DNS name which may use DNS name compression. For these specific record
|
||||||
* record data is first decompressed such that it contains the full uncompressed DNS name. This decompressed data is
|
* types, the record data is first decompressed such that it contains the full uncompressed DNS name. This decompressed
|
||||||
* then provided in `mDataBuffer`, and `mRecordDataLength` will indicate the length of this decompressed data. For all
|
* data is then provided in `mDataBuffer`, and `mRecordDataLength` will indicate the length of this decompressed data.
|
||||||
* other record types, the record data is read and provided as it appears in the received response message.
|
* For all other record types, the record data is read and provided as it appears in the received response message.
|
||||||
*
|
*
|
||||||
* @param[in] aResponse A pointer to the response.
|
* @param[in] aResponse A pointer to the response.
|
||||||
* @param[in] aIndex The record index to retrieve.
|
* @param[in] aIndex The record index to retrieve.
|
||||||
@ -774,7 +774,7 @@ otError otDnsRecordResponseGetQueryName(const otDnsRecordResponse *aResponse,
|
|||||||
* @retval OT_ERROR_NOT_FOUND No record in @p aResponse at @p aIndex.
|
* @retval OT_ERROR_NOT_FOUND No record in @p aResponse at @p aIndex.
|
||||||
* @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse.
|
* @retval OT_ERROR_PARSE Could not parse the records in the @p aResponse.
|
||||||
* @retval OT_ERROR_NO_BUFS The record name does not fit in the provided `mNameBufferSize` in @p aRecordInfo, or
|
* @retval OT_ERROR_NO_BUFS The record name does not fit in the provided `mNameBufferSize` in @p aRecordInfo, or
|
||||||
* failed to allocate buffer to decompress a compressed DNS name (PTR, SRV, CNAME).
|
* failed to allocate buffer to decompress a compressed DNS name.
|
||||||
*/
|
*/
|
||||||
otError otDnsRecordResponseGetRecordInfo(const otDnsRecordResponse *aResponse,
|
otError otDnsRecordResponseGetRecordInfo(const otDnsRecordResponse *aResponse,
|
||||||
uint16_t aIndex,
|
uint16_t aIndex,
|
||||||
|
@ -52,7 +52,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @note This number versions both OpenThread platform and user APIs.
|
* @note This number versions both OpenThread platform and user APIs.
|
||||||
*/
|
*/
|
||||||
#define OPENTHREAD_API_VERSION (501)
|
#define OPENTHREAD_API_VERSION (502)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup api-instance
|
* @addtogroup api-instance
|
||||||
|
@ -378,10 +378,10 @@ exit:
|
|||||||
|
|
||||||
Error Client::Response::ReadRecordInfo(uint16_t aIndex, RecordInfo &aRecordInfo) const
|
Error Client::Response::ReadRecordInfo(uint16_t aIndex, RecordInfo &aRecordInfo) const
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
uint16_t offset;
|
uint16_t offset;
|
||||||
ResourceRecord record;
|
ResourceRecord record;
|
||||||
Message *decompressedData = nullptr;
|
OwnedPtr<Message> decompressedData;
|
||||||
|
|
||||||
if (aIndex < mAnswerRecordCount)
|
if (aIndex < mAnswerRecordCount)
|
||||||
{
|
{
|
||||||
@ -406,43 +406,12 @@ Error Client::Response::ReadRecordInfo(uint16_t aIndex, RecordInfo &aRecordInfo)
|
|||||||
SuccessOrExit(error = Name::ReadName(*mMessage, offset, aRecordInfo.mNameBuffer, aRecordInfo.mNameBufferSize));
|
SuccessOrExit(error = Name::ReadName(*mMessage, offset, aRecordInfo.mNameBuffer, aRecordInfo.mNameBufferSize));
|
||||||
|
|
||||||
SuccessOrExit(error = mMessage->Read(offset, record));
|
SuccessOrExit(error = mMessage->Read(offset, record));
|
||||||
VerifyOrExit(offset + record.GetSize() <= mMessage->GetLength(), error = kErrorParse);
|
|
||||||
offset += sizeof(record);
|
|
||||||
|
|
||||||
aRecordInfo.mRecordType = record.GetType();
|
SuccessOrExit(error = ResourceRecord::DecompressRecordData(*mMessage, offset, decompressedData));
|
||||||
aRecordInfo.mTtl = record.GetTtl();
|
|
||||||
|
|
||||||
// We may need to translate the record data for PTR, CNAME, DNAME, NS
|
|
||||||
// and SRV record since the data format contains a DNS name which
|
|
||||||
// may use compression.
|
|
||||||
|
|
||||||
switch (record.GetType())
|
|
||||||
{
|
|
||||||
case ResourceRecord::kTypePtr:
|
|
||||||
case ResourceRecord::kTypeCname:
|
|
||||||
case ResourceRecord::kTypeDname:
|
|
||||||
case ResourceRecord::kTypeNs:
|
|
||||||
case ResourceRecord::kTypeSrv:
|
|
||||||
decompressedData = mMessage->Get<MessagePool>().Allocate(Message::kTypeOther);
|
|
||||||
VerifyOrExit(decompressedData != nullptr, error = kErrorNoBufs);
|
|
||||||
|
|
||||||
if (record.GetType() == ResourceRecord::kTypeSrv)
|
|
||||||
{
|
|
||||||
uint16_t srvMinLength = sizeof(SrvRecord) - sizeof(ResourceRecord);
|
|
||||||
|
|
||||||
VerifyOrExit(record.GetLength() > srvMinLength, error = kErrorParse);
|
|
||||||
SuccessOrExit(error = decompressedData->AppendBytesFromMessage(*mMessage, offset, srvMinLength));
|
|
||||||
offset += srvMinLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
SuccessOrExit(error = Name(*mMessage, offset).AppendTo(*decompressedData));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
aRecordInfo.mRecordType = record.GetType();
|
||||||
aRecordInfo.mRecordLength = (decompressedData != nullptr) ? decompressedData->GetLength() : record.GetLength();
|
aRecordInfo.mRecordLength = (decompressedData != nullptr) ? decompressedData->GetLength() : record.GetLength();
|
||||||
|
aRecordInfo.mTtl = record.GetTtl();
|
||||||
|
|
||||||
if (aRecordInfo.mDataBuffer == nullptr)
|
if (aRecordInfo.mDataBuffer == nullptr)
|
||||||
{
|
{
|
||||||
@ -458,11 +427,10 @@ Error Client::Response::ReadRecordInfo(uint16_t aIndex, RecordInfo &aRecordInfo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mMessage->ReadBytes(offset, aRecordInfo.mDataBuffer, aRecordInfo.mDataBufferSize);
|
mMessage->ReadBytes(offset + sizeof(ResourceRecord), aRecordInfo.mDataBuffer, aRecordInfo.mDataBufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
FreeMessage(decompressedData);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user