mirror of
https://github.com/espressif/openthread.git
synced 2026-09-07 01:30:11 +00:00
Convert MeshHeader constructors to fail-able initializers (#1157)
This commit makes the following changes: - It converts two of lowpan `MeshHeader` constructors to a fail-able initializers to handle error case where the passed-in argument frame or message is too short. It also updates `MeshForwarder` to use the new initializers instead. - It adds new macro `IgnoreReturnValue()`. This macro is primarily used to indicate the intention of developer that the return value of the function/method can be safely ignored.
This commit is contained in:
committed by
Jonathan Hui
parent
7831bf39ed
commit
3f243ed540
@@ -44,6 +44,7 @@
|
||||
#define otDEFINE_ALIGNED_VAR(name, size, align_type) \
|
||||
align_type name[(((size) + (sizeof (align_type) - 1)) / sizeof (align_type))]
|
||||
|
||||
/* Check the input `ERR` against zero and go to `exit` label if it is non-zero. */
|
||||
#define SuccessOrExit(ERR) \
|
||||
do { \
|
||||
if ((ERR) != 0) { \
|
||||
@@ -51,18 +52,33 @@
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define VerifyOrExit(COND, ACTION) \
|
||||
do { \
|
||||
if (!(COND)) { \
|
||||
ACTION; \
|
||||
goto exit; \
|
||||
} \
|
||||
/* Verify that the `COND` is true, otherwise go to `exit` label. */
|
||||
#define VerifyOrExit(COND, ACTION) \
|
||||
do { \
|
||||
if (!(COND)) { \
|
||||
ACTION; \
|
||||
goto exit; \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
/* Run the passed in statement(s) and go to `exit` label. */
|
||||
#define ExitNow(...) \
|
||||
do { \
|
||||
__VA_ARGS__; \
|
||||
goto exit; \
|
||||
} while (false)
|
||||
|
||||
/*
|
||||
* Run the `statement` and ignore the return value.
|
||||
*
|
||||
* This is primarily used to indicate the intention of developer that the return value of function/method can be
|
||||
* safely ignored.
|
||||
*
|
||||
*/
|
||||
#define IgnoreReturnValue(statement) \
|
||||
do { \
|
||||
if (statement) {} \
|
||||
} while (false)
|
||||
|
||||
|
||||
#endif // CODE_UTILS_HPP_
|
||||
|
||||
@@ -1115,5 +1115,59 @@ exit:
|
||||
return (error == kThreadError_None) ? static_cast<int>(compressedLength) : -1;
|
||||
}
|
||||
|
||||
ThreadError MeshHeader::Init(const uint8_t *aFrame, uint8_t aFrameLength)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
|
||||
VerifyOrExit(aFrameLength >= 1, error = kThreadError_Failed);
|
||||
mDispatchHopsLeft = *aFrame++;
|
||||
aFrameLength--;
|
||||
|
||||
if (IsDeepHopsLeftField())
|
||||
{
|
||||
VerifyOrExit(aFrameLength >= 1, error = kThreadError_Failed);
|
||||
mDeepHopsLeft = *aFrame++;
|
||||
aFrameLength--;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDeepHopsLeft = 0;
|
||||
}
|
||||
|
||||
VerifyOrExit(aFrameLength >= sizeof(mAddress), error = kThreadError_Failed);
|
||||
memcpy(&mAddress, aFrame, sizeof(mAddress));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
ThreadError MeshHeader::Init(const Message &aMessage)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
uint16_t offset = 0;
|
||||
uint16_t bytesRead;
|
||||
|
||||
bytesRead = aMessage.Read(offset, sizeof(mDispatchHopsLeft), &mDispatchHopsLeft);
|
||||
VerifyOrExit(bytesRead == sizeof(mDispatchHopsLeft), error = kThreadError_Failed);
|
||||
offset += bytesRead;
|
||||
|
||||
if (IsDeepHopsLeftField())
|
||||
{
|
||||
bytesRead = aMessage.Read(offset, sizeof(mDeepHopsLeft), &mDeepHopsLeft);
|
||||
VerifyOrExit(bytesRead == sizeof(mDeepHopsLeft), error = kThreadError_Failed);
|
||||
offset += bytesRead;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDeepHopsLeft = 0;
|
||||
}
|
||||
|
||||
bytesRead = aMessage.Read(offset, sizeof(mAddress), &mAddress);
|
||||
VerifyOrExit(bytesRead == sizeof(mAddress), error = kThreadError_Failed);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
} // namespace Lowpan
|
||||
} // namespace Thread
|
||||
|
||||
+23
-29
@@ -232,41 +232,35 @@ public:
|
||||
*/
|
||||
MeshHeader(void) { memset(this, 0, sizeof(*this)); }
|
||||
|
||||
/**
|
||||
* Mesh Header constructor that takes frame @p aFrame as a parameter.
|
||||
*
|
||||
* @param[in] aFrame The pointer to the frame.
|
||||
*
|
||||
*/
|
||||
MeshHeader(const uint8_t *aFrame) {
|
||||
mDispatchHopsLeft = *aFrame++;
|
||||
mDeepHopsLeft = IsDeepHopsLeftField() ? *aFrame++ : 0;
|
||||
memcpy(&mAddress, aFrame, sizeof(mAddress));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mesh Header constructor that takes message object @p aMessage as a parameter.
|
||||
*
|
||||
* @param[in] aMessage The message object.
|
||||
*
|
||||
*/
|
||||
MeshHeader(const Message &aMessage) {
|
||||
aMessage.Read(0, sizeof(mDispatchHopsLeft), &mDispatchHopsLeft);
|
||||
|
||||
if (IsDeepHopsLeftField()) {
|
||||
aMessage.Read(1, sizeof(mDeepHopsLeft) + sizeof(mAddress), &mDeepHopsLeft);
|
||||
}
|
||||
else {
|
||||
aMessage.Read(1, sizeof(mAddress), &mAddress);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes the header.
|
||||
*
|
||||
*/
|
||||
void Init(void) { mDispatchHopsLeft = kDispatch | kSourceShort | kDestinationShort; }
|
||||
|
||||
/**
|
||||
* This method initializes the mesh header from a frame @p aFrame.
|
||||
*
|
||||
* @param[in] aFrame The pointer to the frame.
|
||||
* @param[in] aFrameLength The length of the frame.
|
||||
*
|
||||
* @retval kThreadError_None Mesh Header initialized successfully.
|
||||
* @retval kThreadError_Failed Mesh header could not be initialized from @p aFrame (e.g., frame not long enough).
|
||||
*
|
||||
*/
|
||||
ThreadError Init(const uint8_t *aFrame, uint8_t aFrameLength);
|
||||
|
||||
/**
|
||||
* This method initializes the mesh header from a message object @p aMessage.
|
||||
*
|
||||
* @param[in] aMessage The message object.
|
||||
*
|
||||
* @retval kThreadError_None Mesh Header initialized successfully.
|
||||
* @retval kThreadError_Failed Mesh header could not be initialized from @ aMessage(e.g., not long enough).
|
||||
*
|
||||
*/
|
||||
ThreadError Init(const Message &aMessage);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not the header is a Mesh Header.
|
||||
*
|
||||
|
||||
@@ -394,13 +394,16 @@ ThreadError MeshForwarder::SendMessage(Message &aMessage)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Neighbor *neighbor;
|
||||
Ip6::Header ip6Header;
|
||||
|
||||
uint8_t numChildren;
|
||||
Child *children;
|
||||
|
||||
switch (aMessage.GetType())
|
||||
{
|
||||
case Message::kTypeIp6:
|
||||
{
|
||||
Ip6::Header ip6Header;
|
||||
|
||||
aMessage.Read(0, sizeof(ip6Header), &ip6Header);
|
||||
|
||||
if (!memcmp(&ip6Header.GetDestination(), mMle.GetLinkLocalAllThreadNodesAddress(),
|
||||
@@ -443,10 +446,13 @@ ThreadError MeshForwarder::SendMessage(Message &aMessage)
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case Message::kType6lowpan:
|
||||
{
|
||||
Lowpan::MeshHeader meshHeader(aMessage);
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
|
||||
IgnoreReturnValue(meshHeader.Init(aMessage));
|
||||
|
||||
if ((neighbor = mMle.GetNeighbor(meshHeader.GetDestination())) != NULL &&
|
||||
(neighbor->mMode & Mle::ModeTlv::kModeRxOnWhenIdle) == 0)
|
||||
@@ -573,8 +579,9 @@ Message *MeshForwarder::GetIndirectTransmission(const Child &aChild)
|
||||
|
||||
case Message::kType6lowpan:
|
||||
{
|
||||
Lowpan::MeshHeader meshHeader(*message);
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
|
||||
IgnoreReturnValue(meshHeader.Init(*message));
|
||||
mAddMeshHeader = true;
|
||||
mMeshDest = meshHeader.GetDestination();
|
||||
mMeshSource = meshHeader.GetSource();
|
||||
@@ -594,13 +601,16 @@ exit:
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
ThreadError MeshForwarder::UpdateMeshRoute(Message &aMessage)
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Lowpan::MeshHeader meshHeader(aMessage);
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
Neighbor *neighbor;
|
||||
uint16_t nextHop;
|
||||
|
||||
IgnoreReturnValue(meshHeader.Init(aMessage));
|
||||
|
||||
nextHop = mMle.GetNextHop(meshHeader.GetDestination());
|
||||
|
||||
if (nextHop != Mac::kShortAddrInvalid)
|
||||
@@ -1637,10 +1647,10 @@ void MeshForwarder::HandleMesh(uint8_t *aFrame, uint8_t aFrameLength, const Mac:
|
||||
Message *message = NULL;
|
||||
Mac::Address meshDest;
|
||||
Mac::Address meshSource;
|
||||
Lowpan::MeshHeader meshHeader(aFrame);
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
|
||||
// Length Check
|
||||
VerifyOrExit(meshHeader.GetHeaderLength() <= aFrameLength, error = kThreadError_Drop);
|
||||
// Check the mesh header
|
||||
VerifyOrExit(meshHeader.Init(aFrame, aFrameLength) == kThreadError_None, error = kThreadError_Drop);
|
||||
|
||||
// Security Check: only process Mesh Header frames that had security enabled.
|
||||
VerifyOrExit(aMessageInfo.mLinkSecurity && meshHeader.IsValid(), error = kThreadError_Security);
|
||||
@@ -1705,10 +1715,11 @@ ThreadError MeshForwarder::CheckReachability(uint8_t *aFrame, uint8_t aFrameLeng
|
||||
{
|
||||
ThreadError error = kThreadError_None;
|
||||
Ip6::Header ip6Header;
|
||||
Lowpan::MeshHeader meshHeader(aFrame);
|
||||
Lowpan::MeshHeader meshHeader;
|
||||
|
||||
VerifyOrExit(meshHeader.Init(aFrame, aFrameLength) == kThreadError_None, error = kThreadError_Drop);
|
||||
|
||||
// skip mesh header
|
||||
VerifyOrExit(meshHeader.GetHeaderLength() <= aFrameLength, error = kThreadError_Drop);
|
||||
aFrame += meshHeader.GetHeaderLength();
|
||||
aFrameLength -= meshHeader.GetHeaderLength();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user