[icmp] pass full error-causing message when sending error (#4800)

This commit is contained in:
Jonathan Hui
2020-04-09 09:52:47 -07:00
parent 1f3e4552d6
commit adc62ecfe5
6 changed files with 46 additions and 20 deletions
+5 -3
View File
@@ -90,19 +90,21 @@ exit:
otError Icmp::SendError(IcmpHeader::Type aType,
IcmpHeader::Code aCode,
const MessageInfo &aMessageInfo,
const Header & aHeader)
const Message & aMessage)
{
otError error = OT_ERROR_NONE;
MessageInfo messageInfoLocal;
Message * message = NULL;
IcmpHeader icmp6Header;
Header ip6Header;
messageInfoLocal = aMessageInfo;
VerifyOrExit((message = Get<Ip6>().NewMessage(0)) != NULL, error = OT_ERROR_NO_BUFS);
SuccessOrExit(error = message->SetLength(sizeof(icmp6Header) + sizeof(aHeader)));
SuccessOrExit(error = message->SetLength(sizeof(icmp6Header) + sizeof(ip6Header)));
message->Write(sizeof(icmp6Header), sizeof(aHeader), &aHeader);
aMessage.Read(0, sizeof(ip6Header), &ip6Header);
message->Write(sizeof(icmp6Header), sizeof(ip6Header), &ip6Header);
icmp6Header.Init();
icmp6Header.SetType(aType);
+2 -2
View File
@@ -284,7 +284,7 @@ public:
* @param[in] aType The ICMPv6 message type.
* @param[in] aCode The ICMPv6 message code.
* @param[in] aMessageInfo A reference to the message info.
* @param[in] aHeader The IPv6 header of the error-causing message.
* @param[in] aMessage The error-causing IPv6 message.
*
* @retval OT_ERROR_NONE Successfully enqueued the ICMPv6 error message.
* @retval OT_ERROR_NO_BUFS Insufficient buffers available.
@@ -293,7 +293,7 @@ public:
otError SendError(IcmpHeader::Type aType,
IcmpHeader::Code aCode,
const MessageInfo &aMessageInfo,
const Header & aHeader);
const Message & aMessage);
/**
* This method handles an ICMPv6 message.
+1 -1
View File
@@ -905,7 +905,7 @@ otError Ip6::SendIcmpError(Message &aMessage, IcmpHeader::Type aIcmpType, IcmpHe
messageInfo.SetHopLimit(header.GetHopLimit());
messageInfo.SetLinkInfo(NULL);
SuccessOrExit(error = mIcmp.SendError(aIcmpType, aIcmpCode, messageInfo, header));
SuccessOrExit(error = mIcmp.SendError(aIcmpType, aIcmpCode, messageInfo, aMessage));
exit:
return error;
+1 -1
View File
@@ -332,7 +332,7 @@ otError MeshForwarder::UpdateIp6Route(Message &aMessage)
else
{
#if OPENTHREAD_FTD
error = UpdateIp6RouteFtd(ip6Header);
error = UpdateIp6RouteFtd(ip6Header, aMessage);
#else
OT_ASSERT(false);
#endif
+3 -3
View File
@@ -336,7 +336,7 @@ private:
kMessageEvict, ///< Indicates that the message was evicted.
};
otError CheckReachability(uint8_t * aFrame,
otError CheckReachability(const uint8_t * aFrame,
uint16_t aFrameLength,
const Mac::Address &aMeshSource,
const Mac::Address &aMeshDest);
@@ -390,9 +390,9 @@ private:
uint16_t aMeshDest = 0xffff);
void SendMesh(Message &aMessage, Mac::TxFrame &aFrame);
void SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::Header &aIp6Header);
void SendDestinationUnreachable(uint16_t aMeshSource, const Message &aMessage);
otError UpdateIp6Route(Message &aMessage);
otError UpdateIp6RouteFtd(Ip6::Header &ip6Header);
otError UpdateIp6RouteFtd(Ip6::Header &ip6Header, const Message &aMessage);
otError UpdateMeshRoute(Message &aMessage);
bool UpdateReassemblyList(void);
bool UpdateFragmentLifetime(void);
+34 -10
View File
@@ -404,7 +404,7 @@ exit:
return error;
}
otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header)
otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header, const Message &aMessage)
{
Mle::MleRouter &mle = Get<Mle::MleRouter>();
otError error = OT_ERROR_NONE;
@@ -497,7 +497,7 @@ otError MeshForwarder::UpdateIp6RouteFtd(Ip6::Header &ip6Header)
exit:
if (error == OT_ERROR_NO_ROUTE)
{
SendDestinationUnreachable(mMeshSource, ip6Header);
SendDestinationUnreachable(mMeshSource, aMessage);
}
return error;
@@ -516,32 +516,56 @@ otError MeshForwarder::GetIp6Header(const uint8_t * aFrame,
nextHeaderCompressed);
}
otError MeshForwarder::CheckReachability(uint8_t * aFrame,
otError MeshForwarder::CheckReachability(const uint8_t * aFrame,
uint16_t aFrameLength,
const Mac::Address &aMeshSource,
const Mac::Address &aMeshDest)
{
otError error = OT_ERROR_NONE;
Ip6::Header ip6Header;
otError error = OT_ERROR_NONE;
Ip6::Header ip6Header;
Message * message = NULL;
Lowpan::FragmentHeader fragmentHeader;
uint16_t fragmentHeaderLength;
uint16_t datagramSize = 0;
SuccessOrExit(error = GetIp6Header(aFrame, aFrameLength, aMeshSource, aMeshDest, ip6Header));
if (fragmentHeader.ParseFrom(aFrame, aFrameLength, fragmentHeaderLength) == OT_ERROR_NONE)
{
// Only the first fragment header is followed by a LOWPAN_IPHC header
VerifyOrExit(fragmentHeader.GetDatagramOffset() == 0, error = OT_ERROR_NOT_FOUND);
aFrame += fragmentHeaderLength;
aFrameLength -= fragmentHeaderLength;
datagramSize = fragmentHeader.GetDatagramSize();
}
VerifyOrExit(aFrameLength >= 1 && Lowpan::Lowpan::IsLowpanHc(aFrame), error = OT_ERROR_NOT_FOUND);
error = FrameToMessage(aFrame, aFrameLength, datagramSize, aMeshSource, aMeshDest, message);
SuccessOrExit(error);
message->Read(0, sizeof(ip6Header), &ip6Header);
error = Get<Mle::MleRouter>().CheckReachability(aMeshDest.GetShort(), ip6Header);
exit:
// the message may not contain an IPv6 header
if (error == OT_ERROR_NOT_FOUND)
{
// the message may not contain an IPv6 header
error = OT_ERROR_NONE;
}
else if (error == OT_ERROR_NO_ROUTE)
{
SendDestinationUnreachable(aMeshSource.GetShort(), ip6Header);
SendDestinationUnreachable(aMeshSource.GetShort(), *message);
}
if (message != NULL)
{
message->Free();
}
return error;
}
void MeshForwarder::SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::Header &aIp6Header)
void MeshForwarder::SendDestinationUnreachable(uint16_t aMeshSource, const Message &aMessage)
{
Ip6::MessageInfo messageInfo;
@@ -549,7 +573,7 @@ void MeshForwarder::SendDestinationUnreachable(uint16_t aMeshSource, const Ip6::
messageInfo.GetPeerAddr().SetLocator(aMeshSource);
Get<Ip6::Icmp>().SendError(Ip6::IcmpHeader::kTypeDstUnreach, Ip6::IcmpHeader::kCodeDstUnreachNoRoute, messageInfo,
aIp6Header);
aMessage);
}
void MeshForwarder::HandleMesh(uint8_t * aFrame,