Browse Source

store and concatenate all out-of-sequence fragments

pull/701/head
orignal 8 years ago
parent
commit
1bba0f6bb2
  1. 39
      TunnelEndpoint.cpp
  2. 5
      TunnelEndpoint.h

39
TunnelEndpoint.cpp

@ -117,7 +117,7 @@ namespace tunnel
m.nextFragmentNum = 1; m.nextFragmentNum = 1;
auto ret = m_IncompleteMessages.insert (std::pair<uint32_t, TunnelMessageBlockEx>(msgID, m)); auto ret = m_IncompleteMessages.insert (std::pair<uint32_t, TunnelMessageBlockEx>(msgID, m));
if (ret.second) if (ret.second)
HandleOutOfSequenceFragment (msgID, ret.first->second); HandleOutOfSequenceFragments (msgID, ret.first->second);
else else
LogPrint (eLogError, "TunnelMessage: Incomplete message ", msgID, " already exists"); LogPrint (eLogError, "TunnelMessage: Incomplete message ", msgID, " already exists");
} }
@ -168,7 +168,7 @@ namespace tunnel
else else
{ {
msg.nextFragmentNum++; msg.nextFragmentNum++;
HandleOutOfSequenceFragment (msgID, msg); HandleOutOfSequenceFragments (msgID, msg);
} }
} }
else else
@ -192,19 +192,31 @@ namespace tunnel
void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr<I2NPMessage> data) void TunnelEndpoint::AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr<I2NPMessage> data)
{ {
auto it = m_OutOfSequenceFragments.find (msgID); if (!m_OutOfSequenceFragments.insert ({{msgID, fragmentNum}, {fragmentNum, isLastFragment, data}}).second)
if (it == m_OutOfSequenceFragments.end ()) LogPrint (eLogInfo, "TunnelMessage: duplicate out-of-sequence fragment ", fragmentNum, " of message ", msgID);
m_OutOfSequenceFragments.insert (std::pair<uint32_t, Fragment> (msgID, {fragmentNum, isLastFragment, data}));
} }
void TunnelEndpoint::HandleOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg) void TunnelEndpoint::HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg)
{ {
auto it = m_OutOfSequenceFragments.find (msgID); while (ConcatNextOutOfSequenceFragment (msgID, msg))
{
if (!msg.nextFragmentNum) // message complete
{
HandleNextMessage (msg);
m_IncompleteMessages.erase (msgID);
break;
}
}
}
bool TunnelEndpoint::ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg)
{
auto it = m_OutOfSequenceFragments.find ({msgID, msg.nextFragmentNum});
if (it != m_OutOfSequenceFragments.end ()) if (it != m_OutOfSequenceFragments.end ())
{ {
if (it->second.fragmentNum == msg.nextFragmentNum) if (it->second.fragmentNum == msg.nextFragmentNum)
{ {
LogPrint (eLogWarning, "TunnelMessage: Out-of-sequence fragment ", (int)it->second.fragmentNum, " of message ", msgID, " found"); LogPrint (eLogDebug, "TunnelMessage: Out-of-sequence fragment ", (int)it->second.fragmentNum, " of message ", msgID, " found");
size_t size = it->second.data->GetLength (); size_t size = it->second.data->GetLength ();
if (msg.data->len + size > msg.data->maxLen) if (msg.data->len + size > msg.data->maxLen)
{ {
@ -214,18 +226,19 @@ namespace tunnel
msg.data = newMsg; msg.data = newMsg;
} }
if (msg.data->Concat (it->second.data->GetBuffer (), size) < size) // concatenate out-of-sync fragment if (msg.data->Concat (it->second.data->GetBuffer (), size) < size) // concatenate out-of-sync fragment
LogPrint (eLogError, "Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen); LogPrint (eLogError, "TunnelMessage: Tunnel endpoint I2NP buffer overflow ", msg.data->maxLen);
if (it->second.isLastFragment) if (it->second.isLastFragment)
{
// message complete // message complete
HandleNextMessage (msg); msg.nextFragmentNum = 0;
m_IncompleteMessages.erase (msgID);
}
else else
msg.nextFragmentNum++; msg.nextFragmentNum++;
m_OutOfSequenceFragments.erase (it); m_OutOfSequenceFragments.erase (it);
return true;
} }
else
LogPrint (eLogError, "Tunnel message: next fragment ", (int)it->second.fragmentNum, " of message ", msgID, " mismatch. ", (int)msg.nextFragmentNum, " expected");
} }
return false;
} }
void TunnelEndpoint::HandleNextMessage (const TunnelMessageBlock& msg) void TunnelEndpoint::HandleNextMessage (const TunnelMessageBlock& msg)

5
TunnelEndpoint.h

@ -39,12 +39,13 @@ namespace tunnel
void HandleNextMessage (const TunnelMessageBlock& msg); void HandleNextMessage (const TunnelMessageBlock& msg);
void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr<I2NPMessage> data); void AddOutOfSequenceFragment (uint32_t msgID, uint8_t fragmentNum, bool isLastFragment, std::shared_ptr<I2NPMessage> data);
void HandleOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); bool ConcatNextOutOfSequenceFragment (uint32_t msgID, TunnelMessageBlockEx& msg); // true if something added
void HandleOutOfSequenceFragments (uint32_t msgID, TunnelMessageBlockEx& msg);
private: private:
std::map<uint32_t, TunnelMessageBlockEx> m_IncompleteMessages; std::map<uint32_t, TunnelMessageBlockEx> m_IncompleteMessages;
std::map<uint32_t, Fragment> m_OutOfSequenceFragments; std::map<std::pair<uint32_t, uint8_t>, Fragment> m_OutOfSequenceFragments; // (msgID, fragment#)->fragment
bool m_IsInbound; bool m_IsInbound;
size_t m_NumReceivedBytes; size_t m_NumReceivedBytes;
}; };

Loading…
Cancel
Save