mirror of
https://github.com/espressif/openthread.git
synced 2026-08-08 11:47:46 +00:00
[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:
@@ -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()));
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user