Browse Source

allocate smaller I2NP buffer for fragmented message. Limit number of fragments by 64

pull/1786/head
orignal 2 years ago
parent
commit
771c4a0d02
  1. 31
      libi2pd/SSU2Session.cpp
  2. 3
      libi2pd/SSU2Session.h

31
libi2pd/SSU2Session.cpp

@ -18,6 +18,21 @@ namespace i2p
{ {
namespace transport namespace transport
{ {
void SSU2IncompleteMessage::AttachNextFragment (const uint8_t * fragment, size_t fragmentSize)
{
if (msg->len + fragmentSize > msg->maxLen)
{
LogPrint (eLogInfo, "SSU2: I2NP message size ", msg->maxLen, " is not enough");
auto newMsg = NewI2NPMessage ();
*newMsg = *msg;
msg = newMsg;
}
if (msg->Concat (fragment, fragmentSize) < fragmentSize)
LogPrint (eLogError, "SSU2: I2NP buffer overflow ", msg->maxLen);
nextFragmentNum++;
}
SSU2Session::SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter, SSU2Session::SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter,
std::shared_ptr<const i2p::data::RouterInfo::Address> addr): std::shared_ptr<const i2p::data::RouterInfo::Address> addr):
TransportSession (in_RemoteRouter, SSU2_CONNECT_TIMEOUT), TransportSession (in_RemoteRouter, SSU2_CONNECT_TIMEOUT),
@ -1519,7 +1534,7 @@ namespace transport
void SSU2Session::HandleFirstFragment (const uint8_t * buf, size_t len) void SSU2Session::HandleFirstFragment (const uint8_t * buf, size_t len)
{ {
uint32_t msgID; memcpy (&msgID, buf + 1, 4); uint32_t msgID; memcpy (&msgID, buf + 1, 4);
auto msg = NewI2NPMessage (); auto msg = NewI2NPShortMessage ();
// same format as I2NP message block // same format as I2NP message block
msg->len = msg->offset + len + 7; msg->len = msg->offset + len + 7;
memcpy (msg->GetNTCP2Header (), buf, len); memcpy (msg->GetNTCP2Header (), buf, len);
@ -1557,10 +1572,11 @@ namespace transport
auto it = m_IncompleteMessages.find (msgID); auto it = m_IncompleteMessages.find (msgID);
if (it != m_IncompleteMessages.end ()) if (it != m_IncompleteMessages.end ())
{ {
if (it->second->nextFragmentNum == fragmentNum && it->second->msg) if (it->second->nextFragmentNum == fragmentNum && fragmentNum < SSU2_MAX_NUM_FRAGMENTS &&
it->second->msg)
{ {
// in sequence // in sequence
it->second->msg->Concat (buf + 5, len - 5); it->second->AttachNextFragment (buf + 5, len - 5);
if (isLast) if (isLast)
{ {
it->second->msg->FromNTCP2 (); it->second->msg->FromNTCP2 ();
@ -1569,7 +1585,6 @@ namespace transport
} }
else else
{ {
it->second->nextFragmentNum++;
if (ConcatOutOfSequenceFragments (it->second)) if (ConcatOutOfSequenceFragments (it->second))
{ {
m_Handler.PutNextMessage (std::move (it->second->msg)); m_Handler.PutNextMessage (std::move (it->second->msg));
@ -1589,6 +1604,11 @@ namespace transport
it = m_IncompleteMessages.emplace (msgID, msg).first; it = m_IncompleteMessages.emplace (msgID, msg).first;
} }
// insert out of sequence fragment // insert out of sequence fragment
if (fragmentNum >= SSU2_MAX_NUM_FRAGMENTS)
{
LogPrint (eLogWarning, "SSU2: Fragment number ", fragmentNum, " exceeds ", SSU2_MAX_NUM_FRAGMENTS);
return;
}
auto fragment = std::make_shared<SSU2IncompleteMessage::Fragment> (); auto fragment = std::make_shared<SSU2IncompleteMessage::Fragment> ();
memcpy (fragment->buf, buf + 5, len -5); memcpy (fragment->buf, buf + 5, len -5);
fragment->len = len - 5; fragment->len = len - 5;
@ -1604,10 +1624,9 @@ namespace transport
for (auto it = m->outOfSequenceFragments.begin (); it != m->outOfSequenceFragments.end ();) for (auto it = m->outOfSequenceFragments.begin (); it != m->outOfSequenceFragments.end ();)
if (it->first == m->nextFragmentNum) if (it->first == m->nextFragmentNum)
{ {
m->msg->Concat (it->second->buf, it->second->len); m->AttachNextFragment (it->second->buf, it->second->len);
isLast = it->second->isLast; isLast = it->second->isLast;
it = m->outOfSequenceFragments.erase (it); it = m->outOfSequenceFragments.erase (it);
m->nextFragmentNum++;
} }
else else
break; break;

3
libi2pd/SSU2Session.h

@ -45,6 +45,7 @@ namespace transport
const float SSU2_kAPPA = 1.8; const float SSU2_kAPPA = 1.8;
const size_t SSU2_MAX_OUTGOING_QUEUE_SIZE = 500; // in messages const size_t SSU2_MAX_OUTGOING_QUEUE_SIZE = 500; // in messages
const int SSU2_MAX_NUM_ACK_RANGES = 32; // to send const int SSU2_MAX_NUM_ACK_RANGES = 32; // to send
const uint8_t SSU2_MAX_NUM_FRAGMENTS = 64;
enum SSU2MessageType enum SSU2MessageType
{ {
@ -167,6 +168,8 @@ namespace transport
int nextFragmentNum; int nextFragmentNum;
uint32_t lastFragmentInsertTime; // in seconds uint32_t lastFragmentInsertTime; // in seconds
std::map<int, std::shared_ptr<Fragment> > outOfSequenceFragments; std::map<int, std::shared_ptr<Fragment> > outOfSequenceFragments;
void AttachNextFragment (const uint8_t * fragment, size_t fragmentSize);
}; };
// RouterInfo flags // RouterInfo flags

Loading…
Cancel
Save