mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-02 11:04:00 +01:00
check sequence of fragments
This commit is contained in:
parent
ca6f12a8f1
commit
4e09b39735
|
@ -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())
|
||||||
|
{
|
||||||
|
if (fragmentNum == it->second.nextFragmentNum)
|
||||||
{
|
{
|
||||||
I2NPMessage * incompleteMessage = it->second.data;
|
I2NPMessage * incompleteMessage = it->second.data;
|
||||||
memcpy (incompleteMessage->buf + incompleteMessage->len, fragment, size); // concatenate fragment
|
memcpy (incompleteMessage->buf + incompleteMessage->len, fragment, size); // concatenate fragment
|
||||||
incompleteMessage->len += size;
|
incompleteMessage->len += size;
|
||||||
// TODO: check fragmentNum sequence
|
|
||||||
if (isLastFragment)
|
if (isLastFragment)
|
||||||
{
|
{
|
||||||
// message complete
|
// message complete
|
||||||
HandleNextMessage (it->second);
|
HandleNextMessage (it->second);
|
||||||
m_IncompleteMessages.erase (it);
|
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");
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue