Browse Source

use linked list for out of sequence fragments

pull/1852/head
orignal 2 years ago
parent
commit
bc888167a7
  1. 56
      libi2pd/SSU2Session.cpp
  2. 7
      libi2pd/SSU2Session.h

56
libi2pd/SSU2Session.cpp

@ -35,27 +35,16 @@ namespace transport
bool SSU2IncompleteMessage::ConcatOutOfSequenceFragments () bool SSU2IncompleteMessage::ConcatOutOfSequenceFragments ()
{ {
bool isLast = false; bool isLast = false;
if (nextFragmentNum == 1) while (outOfSequenceFragments)
{ {
if (secondFragment) if (outOfSequenceFragments->fragmentNum == nextFragmentNum)
{ {
AttachNextFragment (secondFragment->buf, secondFragment->len); AttachNextFragment (outOfSequenceFragments->buf, outOfSequenceFragments->len);
isLast = secondFragment->isLast; isLast = outOfSequenceFragments->isLast;
secondFragment = nullptr; if (isLast)
} outOfSequenceFragments = nullptr;
else else
return false; outOfSequenceFragments = outOfSequenceFragments->next;
if (isLast) return true;
}
// might be more
if (outOfSequenceFragments)
{
for (auto it = outOfSequenceFragments->begin (); it != outOfSequenceFragments->end ();)
if (it->first == nextFragmentNum)
{
AttachNextFragment (it->second->buf, it->second->len);
isLast = it->second->isLast;
it = outOfSequenceFragments->erase (it);
} }
else else
break; break;
@ -63,20 +52,28 @@ namespace transport
return isLast; return isLast;
} }
void SSU2IncompleteMessage::AddOutOfSequenceFragment (int fragmentNum, void SSU2IncompleteMessage::AddOutOfSequenceFragment (std::shared_ptr<SSU2IncompleteMessage::Fragment> fragment)
std::shared_ptr<SSU2IncompleteMessage::Fragment> fragment)
{ {
if (!fragmentNum || !fragment) return; // fragment 0 nun allowed if (!fragment || !fragment->fragmentNum) return; // fragment 0 not allowed
if (fragmentNum < nextFragmentNum) return; // already processed if (fragment->fragmentNum < nextFragmentNum) return; // already processed
if (fragmentNum == 1) if (!outOfSequenceFragments)
outOfSequenceFragments = fragment;
else
{
auto frag = outOfSequenceFragments;
std::shared_ptr<Fragment> prev;
do
{ {
if (!secondFragment) secondFragment = fragment; if (fragment->fragmentNum < frag->fragmentNum) break; // found
if (fragment->fragmentNum == frag->fragmentNum) return; // duplicate
prev = frag; frag = frag->next;
} }
while (frag);
fragment->next = frag;
if (prev)
prev->next = fragment;
else else
{ outOfSequenceFragments = fragment;
if (!outOfSequenceFragments)
outOfSequenceFragments.reset (new std::map<int, std::shared_ptr<Fragment> >());
outOfSequenceFragments->emplace (fragmentNum, fragment);
} }
lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch (); lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch ();
} }
@ -1839,8 +1836,9 @@ namespace transport
auto fragment = m_Server.GetFragmentsPool ().AcquireShared (); auto fragment = m_Server.GetFragmentsPool ().AcquireShared ();
memcpy (fragment->buf, buf + 5, len -5); memcpy (fragment->buf, buf + 5, len -5);
fragment->len = len - 5; fragment->len = len - 5;
fragment->fragmentNum = fragmentNum;
fragment->isLast = isLast; fragment->isLast = isLast;
it->second->AddOutOfSequenceFragment (fragmentNum, fragment); it->second->AddOutOfSequenceFragment (fragment);
} }
void SSU2Session::HandleRelayRequest (const uint8_t * buf, size_t len) void SSU2Session::HandleRelayRequest (const uint8_t * buf, size_t len)

7
libi2pd/SSU2Session.h

@ -171,18 +171,19 @@ namespace transport
{ {
uint8_t buf[SSU2_MAX_PACKET_SIZE]; uint8_t buf[SSU2_MAX_PACKET_SIZE];
size_t len; size_t len;
int fragmentNum;
bool isLast; bool isLast;
std::shared_ptr<Fragment> next;
}; };
std::shared_ptr<I2NPMessage> msg; std::shared_ptr<I2NPMessage> msg;
int nextFragmentNum; int nextFragmentNum;
uint32_t lastFragmentInsertTime; // in seconds uint32_t lastFragmentInsertTime; // in seconds
std::shared_ptr<Fragment> secondFragment; // fragment #1 std::shared_ptr<Fragment> outOfSequenceFragments; // #1 and more
std::unique_ptr<std::map<int, std::shared_ptr<Fragment> > > outOfSequenceFragments; // fragments #2 and more
void AttachNextFragment (const uint8_t * fragment, size_t fragmentSize); void AttachNextFragment (const uint8_t * fragment, size_t fragmentSize);
bool ConcatOutOfSequenceFragments (); // true if message complete bool ConcatOutOfSequenceFragments (); // true if message complete
void AddOutOfSequenceFragment (int fragmentNum, std::shared_ptr<Fragment> fragment); void AddOutOfSequenceFragment (std::shared_ptr<Fragment> fragment);
}; };
struct SSU2SentPacket struct SSU2SentPacket

Loading…
Cancel
Save