From 4e4447143196192decdd8c4f101cb7ac991b8b12 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 22 Nov 2022 13:12:52 -0800 Subject: [PATCH] [meshcop] update processing of UDP Encapsulation TLV (#8427) This commit updates how UDP Encapsulation TLV is processed. In particular, when handling a received TMF `kUriProxyTx` message containing this TLV, we allow the TLV to be extended or not. This is aligned with the Thread specification for this TLV. When appending this TLV in `kUriProxyRx` TMF message, we continue to use Extended TLV so to keep the behavior same as before. --- src/core/meshcop/border_agent.cpp | 54 ++++++++++++++++++------------- src/core/meshcop/meshcop_tlvs.hpp | 46 ++++++-------------------- 2 files changed, 40 insertions(+), 60 deletions(-) diff --git a/src/core/meshcop/border_agent.cpp b/src/core/meshcop/border_agent.cpp index d3caf88d2..6d1a344bb 100644 --- a/src/core/meshcop/border_agent.cpp +++ b/src/core/meshcop/border_agent.cpp @@ -254,31 +254,35 @@ template <> void BorderAgent::HandleTmf(Coap::Message &aMessage, co { OT_UNUSED_VARIABLE(aMessageInfo); - Message * message = nullptr; - Ip6::MessageInfo messageInfo; - uint16_t offset; - Error error = kErrorNone; - UdpEncapsulationTlv tlv; + Error error = kErrorNone; + Message * message = nullptr; + Ip6::MessageInfo messageInfo; + uint16_t offset; + uint16_t length; + UdpEncapsulationTlvHeader udpEncapHeader; VerifyOrExit(mState != kStateStopped); - SuccessOrExit(error = Tlv::FindTlvOffset(aMessage, Tlv::kUdpEncapsulation, offset)); - SuccessOrExit(error = aMessage.Read(offset, tlv)); + SuccessOrExit(error = Tlv::FindTlvValueOffset(aMessage, Tlv::kUdpEncapsulation, offset, length)); + + SuccessOrExit(error = aMessage.Read(offset, udpEncapHeader)); + offset += sizeof(UdpEncapsulationTlvHeader); + length -= sizeof(UdpEncapsulationTlvHeader); + + VerifyOrExit(udpEncapHeader.GetSourcePort() > 0 && udpEncapHeader.GetDestinationPort() > 0, error = kErrorDrop); VerifyOrExit((message = Get().NewMessage(0)) != nullptr, error = kErrorNoBufs); - SuccessOrExit(error = message->SetLength(tlv.GetUdpLength())); - aMessage.CopyTo(offset + sizeof(tlv), 0, tlv.GetUdpLength(), *message); + SuccessOrExit(error = message->SetLength(length)); + aMessage.CopyTo(/* aSroOffset */ offset, /* aDestOffset */ 0, length, /* aDestMsg */ *message); - VerifyOrExit(tlv.GetSourcePort() > 0 && tlv.GetDestinationPort() > 0, error = kErrorDrop); - - messageInfo.SetSockPort(tlv.GetSourcePort()); + messageInfo.SetSockPort(udpEncapHeader.GetSourcePort()); messageInfo.SetSockAddr(mCommissionerAloc.GetAddress()); - messageInfo.SetPeerPort(tlv.GetDestinationPort()); + messageInfo.SetPeerPort(udpEncapHeader.GetDestinationPort()); SuccessOrExit(error = Tlv::Find(aMessage, messageInfo.GetPeerAddr())); SuccessOrExit(error = Get().SendDatagram(*message, messageInfo, Ip6::kProtoUdp)); - mUdpProxyPort = tlv.GetSourcePort(); + mUdpProxyPort = udpEncapHeader.GetSourcePort(); LogInfo("Proxy transmit sent to %s", messageInfo.GetPeerAddr().ToString().AsCString()); @@ -306,19 +310,23 @@ bool BorderAgent::HandleUdpReceive(const Message &aMessage, const Ip6::MessageIn VerifyOrExit(message != nullptr, error = kErrorNoBufs); { - UdpEncapsulationTlv tlv; - uint16_t offset; - uint16_t udpLength = aMessage.GetLength() - aMessage.GetOffset(); + ExtendedTlv extTlv; + UdpEncapsulationTlvHeader udpEncapHeader; + uint16_t offset; + uint16_t udpLength = aMessage.GetLength() - aMessage.GetOffset(); - tlv.Init(); - tlv.SetSourcePort(aMessageInfo.GetPeerPort()); - tlv.SetDestinationPort(aMessageInfo.GetSockPort()); - tlv.SetUdpLength(udpLength); - SuccessOrExit(error = message->Append(tlv)); + extTlv.SetType(Tlv::kUdpEncapsulation); + extTlv.SetLength(sizeof(UdpEncapsulationTlvHeader) + udpLength); + SuccessOrExit(error = message->Append(extTlv)); + + udpEncapHeader.SetSourcePort(aMessageInfo.GetPeerPort()); + udpEncapHeader.SetDestinationPort(aMessageInfo.GetSockPort()); + SuccessOrExit(error = message->Append(udpEncapHeader)); offset = message->GetLength(); SuccessOrExit(error = message->SetLength(offset + udpLength)); - aMessage.CopyTo(aMessage.GetOffset(), offset, udpLength, *message); + aMessage.CopyTo(/* aSrcOffset */ aMessage.GetOffset(), /* aDestOffset */ offset, udpLength, + /* aDestMsg */ *message); } SuccessOrExit(error = Tlv::Append(*message, aMessageInfo.GetPeerAddr())); diff --git a/src/core/meshcop/meshcop_tlvs.hpp b/src/core/meshcop/meshcop_tlvs.hpp index 462eaa0ca..fac5836a1 100644 --- a/src/core/meshcop/meshcop_tlvs.hpp +++ b/src/core/meshcop/meshcop_tlvs.hpp @@ -1734,32 +1734,19 @@ private: } OT_TOOL_PACKED_END; /** - * This class implements UDP Encapsulation TLV generation and parsing. + * This class defines UDP Encapsulation TLV types and constants. + * + */ +typedef TlvInfo UdpEncapsulationTlv; + +/** + * This class represents UDP Encapsulation TLV value header (source and destination ports). * */ OT_TOOL_PACKED_BEGIN -class UdpEncapsulationTlv : public ExtendedTlv, public TlvInfo +class UdpEncapsulationTlvHeader { public: - /** - * This method initializes the TLV. - * - */ - void Init(void) - { - SetType(MeshCoP::Tlv::kUdpEncapsulation); - SetLength(sizeof(*this) - sizeof(ExtendedTlv)); - } - - /** - * This method indicates whether or not the TLV appears to be well-formed. - * - * @retval TRUE If the TLV appears to be well-formed. - * @retval FALSE If the TLV does not appear to be well-formed. - * - */ - bool IsValid(void) const { return GetLength() >= sizeof(*this) - sizeof(ExtendedTlv); } - /** * This method returns the source port. * @@ -1792,25 +1779,10 @@ public: */ void SetDestinationPort(uint16_t aDestinationPort) { mDestinationPort = HostSwap16(aDestinationPort); } - /** - * This method returns the calculated UDP length. - * - * @returns The calculated UDP length. - * - */ - uint16_t GetUdpLength(void) const { return GetLength() - sizeof(mSourcePort) - sizeof(mDestinationPort); } - - /** - * This method updates the UDP length. - * - * @param[in] aLength The length of UDP payload in bytes. - * - */ - void SetUdpLength(uint16_t aLength) { SetLength(sizeof(mSourcePort) + sizeof(mDestinationPort) + aLength); } - private: uint16_t mSourcePort; uint16_t mDestinationPort; + // Followed by the UDP Payload. } OT_TOOL_PACKED_END; /**