check sequence of fragments

This commit is contained in:
orignal 2014-06-11 10:56:20 -04:00
parent ca6f12a8f1
commit 4e09b39735
2 changed files with 30 additions and 12 deletions

View File

@ -26,7 +26,8 @@ namespace tunnel
bool isFollowOnFragment = flag & 0x80, isLastFragment = true; bool isFollowOnFragment = flag & 0x80, isLastFragment = true;
uint32_t msgID = 0; uint32_t msgID = 0;
TunnelMessageBlock m; int fragmentNum = 0;
TunnelMessageBlockEx m;
if (!isFollowOnFragment) if (!isFollowOnFragment)
{ {
// first fragment // first fragment
@ -68,7 +69,7 @@ namespace tunnel
// follow on // follow on
msgID = be32toh (*(uint32_t *)fragment); // MessageID msgID = be32toh (*(uint32_t *)fragment); // MessageID
fragment += 4; fragment += 4;
int fragmentNum = (flag >> 1) & 0x3F; // 6 bits fragmentNum = (flag >> 1) & 0x3F; // 6 bits
isLastFragment = flag & 0x01; isLastFragment = flag & 0x01;
LogPrint ("Follow on fragment ", fragmentNum, " of message ", msgID, isLastFragment ? " last" : " non-last"); LogPrint ("Follow on fragment ", fragmentNum, " of message ", msgID, isLastFragment ? " last" : " non-last");
} }
@ -101,22 +102,34 @@ namespace tunnel
if (msgID) // msgID is presented, assume message is fragmented if (msgID) // msgID is presented, assume message is fragmented
{ {
if (!isFollowOnFragment) // create new incomlete message if (!isFollowOnFragment) // create new incomlete message
{
m.nextFragmentNum = 1;
m_IncompleteMessages[msgID] = m; m_IncompleteMessages[msgID] = m;
}
else else
{ {
auto it = m_IncompleteMessages.find (msgID); auto it = m_IncompleteMessages.find (msgID);
if (it != m_IncompleteMessages.end()) if (it != m_IncompleteMessages.end())
{ {
I2NPMessage * incompleteMessage = it->second.data; if (fragmentNum == it->second.nextFragmentNum)
memcpy (incompleteMessage->buf + incompleteMessage->len, fragment, size); // concatenate fragment
incompleteMessage->len += size;
// TODO: check fragmentNum sequence
if (isLastFragment)
{ {
// message complete I2NPMessage * incompleteMessage = it->second.data;
HandleNextMessage (it->second); memcpy (incompleteMessage->buf + incompleteMessage->len, fragment, size); // concatenate fragment
m_IncompleteMessages.erase (it); 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 else
LogPrint ("First fragment of message ", msgID, " not found. Discarded"); LogPrint ("First fragment of message ", msgID, " not found. Discarded");

View File

@ -26,7 +26,12 @@ namespace tunnel
private: 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; size_t m_NumReceivedBytes;
}; };
} }