mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 12:24:19 +00:00
use linked list for out of sequence fragments
This commit is contained in:
parent
6ca6591c43
commit
bc888167a7
@ -35,48 +35,45 @@ 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
|
||||||
|
outOfSequenceFragments = outOfSequenceFragments->next;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
break;
|
||||||
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
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
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;
|
||||||
if (!secondFragment) secondFragment = fragment;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!outOfSequenceFragments)
|
auto frag = outOfSequenceFragments;
|
||||||
outOfSequenceFragments.reset (new std::map<int, std::shared_ptr<Fragment> >());
|
std::shared_ptr<Fragment> prev;
|
||||||
outOfSequenceFragments->emplace (fragmentNum, fragment);
|
do
|
||||||
|
{
|
||||||
|
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
|
||||||
|
outOfSequenceFragments = 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)
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user