From 404c80455a1ff7bdfdfaa523919d1bc712ce5be5 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Sat, 21 Feb 2026 20:45:22 -0800 Subject: [PATCH] [message] add `DetermineLengthAfterOffset()` helper method (#12508) This commit adds `DetermineLengthAfterOffset()` helper method to `Message` which returns the number of bytes in the message from the current offset to the end of the message. This pattern is commonly used in many places to determine the remaining length of the payload. This commit updates various core modules including MeshCoP, 6LoWPAN, IPv6, TCP, and MeshForwarder to use this new helper. --- src/core/common/heap_data.cpp | 2 +- src/core/common/message.cpp | 5 +++++ src/core/common/message.hpp | 7 +++++++ src/core/meshcop/border_agent.cpp | 2 +- src/core/meshcop/meshcop.cpp | 2 +- src/core/net/checksum.cpp | 4 ++-- src/core/net/dns_client.cpp | 4 ++-- src/core/net/dns_dso.cpp | 2 +- src/core/net/ip6.cpp | 2 +- src/core/net/nat64_translator.cpp | 4 ++-- src/core/net/tcp6.cpp | 2 +- src/core/thread/lowpan.cpp | 2 +- src/core/thread/mesh_forwarder.cpp | 2 +- src/core/thread/message_framer.cpp | 4 ++-- 14 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/core/common/heap_data.cpp b/src/core/common/heap_data.cpp index 1da083817..fcdfe0524 100644 --- a/src/core/common/heap_data.cpp +++ b/src/core/common/heap_data.cpp @@ -54,7 +54,7 @@ exit: Error Data::SetFrom(const Message &aMessage) { - return SetFrom(aMessage, aMessage.GetOffset(), aMessage.GetLength() - aMessage.GetOffset()); + return SetFrom(aMessage, aMessage.GetOffset(), aMessage.DetermineLengthAfterOffset()); } Error Data::SetFrom(const Message &aMessage, uint16_t aOffset, uint16_t aLength) diff --git a/src/core/common/message.cpp b/src/core/common/message.cpp index 947a722a1..06a498918 100644 --- a/src/core/common/message.cpp +++ b/src/core/common/message.cpp @@ -327,6 +327,11 @@ void Message::SetOffset(uint16_t aOffset) GetMetadata().mOffset = aOffset; } +uint16_t Message::DetermineLengthAfterOffset(void) const +{ + return (GetOffset() <= GetLength()) ? GetLength() - GetOffset() : 0; +} + bool Message::IsMleCommand(Mle::Command aMleCommand) const { return (GetSubType() == kSubTypeMle) && (GetMetadata().mMleCommand == aMleCommand); diff --git a/src/core/common/message.hpp b/src/core/common/message.hpp index 39f0863db..251752c36 100644 --- a/src/core/common/message.hpp +++ b/src/core/common/message.hpp @@ -537,6 +537,13 @@ public: */ void SetOffset(uint16_t aOffset); + /** + * Determines the length (number of bytes) in the message from the current message offset to the end of the message. + * + * @return Number of bytes in the message starting from the current message offset to the end of the message. + */ + uint16_t DetermineLengthAfterOffset(void) const; + /** * Returns the type of the message. * diff --git a/src/core/meshcop/border_agent.cpp b/src/core/meshcop/border_agent.cpp index 943fb5f03..31e2258a1 100644 --- a/src/core/meshcop/border_agent.cpp +++ b/src/core/meshcop/border_agent.cpp @@ -821,7 +821,7 @@ void Manager::CoapDtlsSession::HandleLeaderResponseToFwdTmf(const ForwardContext forwardMessage->Init(Coap::kTypeNonConfirmable, static_cast(aResponse->GetCode()))); SuccessOrExit(error = forwardMessage->WriteToken(aForwardContext.mToken)); - if (aResponse->mMessage.GetLength() > aResponse->mMessage.GetOffset()) + if (aResponse->mMessage.DetermineLengthAfterOffset() > 0) { SuccessOrExit(error = forwardMessage->AppendPayloadMarker()); } diff --git a/src/core/meshcop/meshcop.cpp b/src/core/meshcop/meshcop.cpp index d924e8b18..ef67bb58b 100644 --- a/src/core/meshcop/meshcop.cpp +++ b/src/core/meshcop/meshcop.cpp @@ -250,7 +250,7 @@ void LogCertMessage(const char *aText, const Coap::Message &aMessage) OT_UNUSED_VARIABLE(aText); uint8_t buf[Buffer::kSize]; - uint16_t length = aMessage.GetLength() - aMessage.GetOffset(); + uint16_t length = aMessage.DetermineLengthAfterOffset(); VerifyOrExit(length <= sizeof(buf)); aMessage.ReadBytes(aMessage.GetOffset(), buf, length); diff --git a/src/core/net/checksum.cpp b/src/core/net/checksum.cpp index c343fe54b..237cac3b8 100644 --- a/src/core/net/checksum.cpp +++ b/src/core/net/checksum.cpp @@ -100,7 +100,7 @@ void Checksum::Calculate(const Ip6::Address &aSource, const Message &aMessage) { Message::Chunk chunk; - uint16_t length = aMessage.GetLength() - aMessage.GetOffset(); + uint16_t length = aMessage.DetermineLengthAfterOffset(); // Pseudo-header for checksum calculation (RFC-2460). @@ -126,7 +126,7 @@ void Checksum::Calculate(const Ip4::Address &aSource, const Message &aMessage) { Message::Chunk chunk; - uint16_t length = aMessage.GetLength() - aMessage.GetOffset(); + uint16_t length = aMessage.DetermineLengthAfterOffset(); // Pseudo-header for checksum calculation (RFC-768/792/793). // Note: ICMP checksum won't count the pseudo header like TCP and UDP. diff --git a/src/core/net/dns_client.cpp b/src/core/net/dns_client.cpp index feaf1b451..66d2c41c7 100644 --- a/src/core/net/dns_client.cpp +++ b/src/core/net/dns_client.cpp @@ -1199,7 +1199,7 @@ Error Client::SendQuery(Query &aQuery, QueryInfo &aInfo, bool aUpdateTimer) } #endif - length = message->GetLength() - message->GetOffset(); + length = message->DetermineLengthAfterOffset(); if (aInfo.mConfig.GetTransportProto() == QueryConfig::kDnsTransportTcp) #if OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_ENABLE @@ -1893,7 +1893,7 @@ exit: #if OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_ENABLE void Client::PrepareTcpMessage(Message &aMessage) { - uint16_t length = aMessage.GetLength() - aMessage.GetOffset(); + uint16_t length = aMessage.DetermineLengthAfterOffset(); // Prepending the DNS query with length of the packet according to RFC1035. BigEndian::WriteUint16(length, mSendBufferBytes + mSendLink.mLength); diff --git a/src/core/net/dns_dso.cpp b/src/core/net/dns_dso.cpp index 24382f794..577894485 100644 --- a/src/core/net/dns_dso.cpp +++ b/src/core/net/dns_dso.cpp @@ -766,7 +766,7 @@ Error Dso::Connection::ReadPrimaryTlv(const Message &aMessage, Tlv::Type &aPrima aPrimaryTlvType = Tlv::kReservedType; SuccessOrExit(aMessage.Read(aMessage.GetOffset(), tlv)); - VerifyOrExit(aMessage.GetOffset() + tlv.GetSize() <= aMessage.GetLength(), error = kErrorParse); + VerifyOrExit(tlv.GetSize() <= aMessage.DetermineLengthAfterOffset(), error = kErrorParse); aPrimaryTlvType = tlv.GetType(); error = kErrorNone; diff --git a/src/core/net/ip6.cpp b/src/core/net/ip6.cpp index e9d0f8b19..36b4db582 100644 --- a/src/core/net/ip6.cpp +++ b/src/core/net/ip6.cpp @@ -565,7 +565,7 @@ Error Ip6::FragmentDatagram(Message &aMessage, uint8_t aIpProto) uint16_t maxPayloadFragment = FragmentHeader::MakeDivisibleByEight(kMinimalMtu - aMessage.GetOffset() - sizeof(fragmentHeader)); - uint16_t payloadLeft = aMessage.GetLength() - aMessage.GetOffset(); + uint16_t payloadLeft = aMessage.DetermineLengthAfterOffset(); SuccessOrExit(error = aMessage.Read(0, header)); header.SetNextHeader(kProtoFragment); diff --git a/src/core/net/nat64_translator.cpp b/src/core/net/nat64_translator.cpp index 5847e8489..f465ac798 100644 --- a/src/core/net/nat64_translator.cpp +++ b/src/core/net/nat64_translator.cpp @@ -187,7 +187,7 @@ Error Translator::TranslateIp6ToIp4(Message &aMessage) } // TODO: Implement the logic for replying ICMP messages. - ip4Header.SetTotalLength(sizeof(Ip4::Header) + aMessage.GetLength() - aMessage.GetOffset()); + ip4Header.SetTotalLength(sizeof(Ip4::Header) + aMessage.DetermineLengthAfterOffset()); Checksum::UpdateMessageChecksum(aMessage, ip4Header.GetSource(), ip4Header.GetDestination(), ip4Header.GetProtocol()); @@ -285,7 +285,7 @@ Error Translator::TranslateIp4ToIp6(Message &aMessage) } // TODO: Implement the logic for replying ICMP datagrams. - ip6Header.SetPayloadLength(aMessage.GetLength() - aMessage.GetOffset()); + ip6Header.SetPayloadLength(aMessage.DetermineLengthAfterOffset()); Checksum::UpdateMessageChecksum(aMessage, ip6Header.GetSource(), ip6Header.GetDestination(), ip6Header.GetNextHeader()); diff --git a/src/core/net/tcp6.cpp b/src/core/net/tcp6.cpp index f3f707acf..f7a2f852d 100644 --- a/src/core/net/tcp6.cpp +++ b/src/core/net/tcp6.cpp @@ -633,7 +633,7 @@ Error Tcp::HandleMessage(ot::Ip6::Header &aIp6Header, Message &aMessage, Message struct tcplp_signals sig; int nextAction; - VerifyOrExit(length == aMessage.GetLength() - aMessage.GetOffset(), error = kErrorParse); + VerifyOrExit(length == aMessage.DetermineLengthAfterOffset(), error = kErrorParse); VerifyOrExit(length >= sizeof(Tcp::Header), error = kErrorParse); SuccessOrExit(error = aMessage.Read(aMessage.GetOffset() + offsetof(struct tcphdr, th_off_x2), headerSize)); headerSize = static_cast((headerSize >> TH_OFF_SHIFT) << 2); diff --git a/src/core/thread/lowpan.cpp b/src/core/thread/lowpan.cpp index 284b2c31c..58790c0fc 100644 --- a/src/core/thread/lowpan.cpp +++ b/src/core/thread/lowpan.cpp @@ -498,7 +498,7 @@ Error Lowpan::CompressExtensionHeader(Message &aMessage, FrameBuilder &aFrameBui } } - VerifyOrExit(aMessage.GetOffset() + len + padLength <= aMessage.GetLength(), error = kErrorParse); + VerifyOrExit(len + padLength <= aMessage.DetermineLengthAfterOffset(), error = kErrorParse); aNextHeader = static_cast(extHeader.GetNextHeader()); diff --git a/src/core/thread/mesh_forwarder.cpp b/src/core/thread/mesh_forwarder.cpp index 20cb111d8..7bceab642 100644 --- a/src/core/thread/mesh_forwarder.cpp +++ b/src/core/thread/mesh_forwarder.cpp @@ -1178,7 +1178,7 @@ exit: if (error == kErrorNone) { - if (message->GetOffset() >= message->GetLength()) + if (message->DetermineLengthAfterOffset() == 0) { mReassemblyList.Dequeue(*message); IgnoreError(HandleDatagram(*message, aRxInfo.GetSrcAddr())); diff --git a/src/core/thread/message_framer.cpp b/src/core/thread/message_framer.cpp index 35243d3df..9cb9424bf 100644 --- a/src/core/thread/message_framer.cpp +++ b/src/core/thread/message_framer.cpp @@ -278,7 +278,7 @@ start: frameBuilder.SetMaxLength(maxFrameLength); - payloadLength = aMessage.GetLength() - aMessage.GetOffset(); + payloadLength = aMessage.DetermineLengthAfterOffset(); if (aAddFragHeader || (payloadLength > frameBuilder.GetRemainingLength())) { @@ -319,7 +319,7 @@ start: aMessage.GetOffset()); SuccessOrAssert(frameBuilder.Append(nextFragHeader)); - payloadLength = aMessage.GetLength() - aMessage.GetOffset(); + payloadLength = aMessage.DetermineLengthAfterOffset(); } if (payloadLength > frameBuilder.GetRemainingLength())