[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.
This commit is contained in:
Abtin Keshavarzian
2022-11-22 13:12:52 -08:00
committed by GitHub
parent b102e4172c
commit 4e44471431
2 changed files with 40 additions and 60 deletions
+31 -23
View File
@@ -254,31 +254,35 @@ template <> void BorderAgent::HandleTmf<kUriProxyTx>(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<Ip6::Udp>().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<Ip6AddressTlv>(aMessage, messageInfo.GetPeerAddr()));
SuccessOrExit(error = Get<Ip6::Udp>().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<Ip6AddressTlv>(*message, aMessageInfo.GetPeerAddr()));
+9 -37
View File
@@ -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<MeshCoP::Tlv::kUdpEncapsulation> UdpEncapsulationTlv;
/**
* This class represents UDP Encapsulation TLV value header (source and destination ports).
*
*/
OT_TOOL_PACKED_BEGIN
class UdpEncapsulationTlv : public ExtendedTlv, public TlvInfo<MeshCoP::Tlv::kUdpEncapsulation>
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;
/**