Skip to content

Commit

Permalink
check sequence of fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
orignal committed Jun 11, 2014
1 parent ca6f12a commit 4e09b39
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 12 deletions.
35 changes: 24 additions & 11 deletions TunnelEndpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ namespace tunnel

bool isFollowOnFragment = flag & 0x80, isLastFragment = true;
uint32_t msgID = 0;
TunnelMessageBlock m;
int fragmentNum = 0;
TunnelMessageBlockEx m;
if (!isFollowOnFragment)
{
// first fragment
Expand Down Expand Up @@ -68,7 +69,7 @@ namespace tunnel
// follow on
msgID = be32toh (*(uint32_t *)fragment); // MessageID
fragment += 4;
int fragmentNum = (flag >> 1) & 0x3F; // 6 bits
fragmentNum = (flag >> 1) & 0x3F; // 6 bits
isLastFragment = flag & 0x01;
LogPrint ("Follow on fragment ", fragmentNum, " of message ", msgID, isLastFragment ? " last" : " non-last");
}
Expand Down Expand Up @@ -101,22 +102,34 @@ namespace tunnel
if (msgID) // msgID is presented, assume message is fragmented
{
if (!isFollowOnFragment) // create new incomlete message
{
m.nextFragmentNum = 1;
m_IncompleteMessages[msgID] = m;
}
else
{
auto it = m_IncompleteMessages.find (msgID);
if (it != m_IncompleteMessages.end())
{
I2NPMessage * incompleteMessage = it->second.data;
memcpy (incompleteMessage->buf + incompleteMessage->len, fragment, size); // concatenate fragment
incompleteMessage->len += size;
// TODO: check fragmentNum sequence
if (isLastFragment)
if (fragmentNum == it->second.nextFragmentNum)
{
// message complete
HandleNextMessage (it->second);
m_IncompleteMessages.erase (it);
}
I2NPMessage * incompleteMessage = it->second.data;
memcpy (incompleteMessage->buf + incompleteMessage->len, fragment, size); // concatenate fragment
incompleteMessage->len += size;
if (isLastFragment)
{
// message complete
HandleNextMessage (it->second);
m_IncompleteMessages.erase (it);
}
else
it->second.nextFragmentNum++;
}
else
{
LogPrint ("Unexpected fragment ", fragmentNum, " instead ", it->second.nextFragmentNum, " of message ", msgID, ". Discarded");
m_IncompleteMessages.erase (it); // TODO: store unexpect fragment for a while
}
}
else
LogPrint ("First fragment of message ", msgID, " not found. Discarded");
Expand Down
7 changes: 6 additions & 1 deletion TunnelEndpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ namespace tunnel

private:

std::map<uint32_t, TunnelMessageBlock> m_IncompleteMessages;
struct TunnelMessageBlockEx: public TunnelMessageBlock
{
uint8_t nextFragmentNum;
};

std::map<uint32_t, TunnelMessageBlockEx> m_IncompleteMessages;
size_t m_NumReceivedBytes;
};
}
Expand Down

0 comments on commit 4e09b39

Please sign in to comment.