mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 13:27:17 +01:00
use separate pointer to second fragment of incomplete message
This commit is contained in:
parent
324ace103b
commit
993dc72ce6
|
@ -32,7 +32,55 @@ namespace transport
|
|||
nextFragmentNum++;
|
||||
}
|
||||
|
||||
bool SSU2IncompleteMessage::ConcatOutOfSequenceFragments ()
|
||||
{
|
||||
bool isLast = false;
|
||||
if (nextFragmentNum == 1)
|
||||
{
|
||||
if (secondFragment)
|
||||
{
|
||||
AttachNextFragment (secondFragment->buf, secondFragment->len);
|
||||
isLast = secondFragment->isLast;
|
||||
secondFragment = nullptr;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
||||
void SSU2IncompleteMessage::AddOutOfSequenceFragment (int fragmentNum,
|
||||
std::shared_ptr<SSU2IncompleteMessage::Fragment> fragment)
|
||||
{
|
||||
if (!fragmentNum || !fragment) return; // fragment 0 nun allowed
|
||||
if (fragmentNum < nextFragmentNum) return; // already processed
|
||||
if (fragmentNum == 1)
|
||||
{
|
||||
if (!secondFragment) secondFragment = fragment;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!outOfSequenceFragments)
|
||||
outOfSequenceFragments.reset (new std::map<int, std::shared_ptr<Fragment> >());
|
||||
outOfSequenceFragments->emplace (fragmentNum, fragment);
|
||||
}
|
||||
lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch ();
|
||||
}
|
||||
|
||||
SSU2Session::SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter,
|
||||
std::shared_ptr<const i2p::data::RouterInfo::Address> addr):
|
||||
TransportSession (in_RemoteRouter, SSU2_CONNECT_TIMEOUT),
|
||||
|
@ -1733,7 +1781,7 @@ namespace transport
|
|||
m->msg = msg;
|
||||
m->nextFragmentNum = 1;
|
||||
m->lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch ();
|
||||
if (found && ConcatOutOfSequenceFragments (m))
|
||||
if (found && m->ConcatOutOfSequenceFragments ())
|
||||
{
|
||||
// we have all follow-on fragments already
|
||||
m->msg->FromNTCP2 ();
|
||||
|
@ -1764,7 +1812,7 @@ namespace transport
|
|||
}
|
||||
else
|
||||
{
|
||||
if (ConcatOutOfSequenceFragments (it->second))
|
||||
if (it->second->ConcatOutOfSequenceFragments ())
|
||||
{
|
||||
HandleI2NPMsg (std::move (it->second->msg));
|
||||
m_IncompleteMessages.erase (it);
|
||||
|
@ -1792,24 +1840,7 @@ namespace transport
|
|||
memcpy (fragment->buf, buf + 5, len -5);
|
||||
fragment->len = len - 5;
|
||||
fragment->isLast = isLast;
|
||||
it->second->outOfSequenceFragments.emplace (fragmentNum, fragment);
|
||||
it->second->lastFragmentInsertTime = i2p::util::GetSecondsSinceEpoch ();
|
||||
}
|
||||
|
||||
bool SSU2Session::ConcatOutOfSequenceFragments (std::shared_ptr<SSU2IncompleteMessage> m)
|
||||
{
|
||||
if (!m) return false;
|
||||
bool isLast = false;
|
||||
for (auto it = m->outOfSequenceFragments.begin (); it != m->outOfSequenceFragments.end ();)
|
||||
if (it->first == m->nextFragmentNum)
|
||||
{
|
||||
m->AttachNextFragment (it->second->buf, it->second->len);
|
||||
isLast = it->second->isLast;
|
||||
it = m->outOfSequenceFragments.erase (it);
|
||||
}
|
||||
else
|
||||
break;
|
||||
return isLast;
|
||||
it->second->AddOutOfSequenceFragment (fragmentNum, fragment);
|
||||
}
|
||||
|
||||
void SSU2Session::HandleRelayRequest (const uint8_t * buf, size_t len)
|
||||
|
|
|
@ -177,9 +177,12 @@ namespace transport
|
|||
std::shared_ptr<I2NPMessage> msg;
|
||||
int nextFragmentNum;
|
||||
uint32_t lastFragmentInsertTime; // in seconds
|
||||
std::map<int, std::shared_ptr<Fragment> > outOfSequenceFragments;
|
||||
std::shared_ptr<Fragment> secondFragment; // fragment #1
|
||||
std::unique_ptr<std::map<int, std::shared_ptr<Fragment> > > outOfSequenceFragments; // fragments #2 and more
|
||||
|
||||
void AttachNextFragment (const uint8_t * fragment, size_t fragmentSize);
|
||||
bool ConcatOutOfSequenceFragments (); // true if message complete
|
||||
void AddOutOfSequenceFragment (int fragmentNum, std::shared_ptr<Fragment> fragment);
|
||||
};
|
||||
|
||||
struct SSU2SentPacket
|
||||
|
@ -306,7 +309,6 @@ namespace transport
|
|||
bool UpdateReceivePacketNum (uint32_t packetNum); // for Ack, returns false if duplicate
|
||||
void HandleFirstFragment (const uint8_t * buf, size_t len);
|
||||
void HandleFollowOnFragment (const uint8_t * buf, size_t len);
|
||||
bool ConcatOutOfSequenceFragments (std::shared_ptr<SSU2IncompleteMessage> m); // true if message complete
|
||||
void HandleRelayRequest (const uint8_t * buf, size_t len);
|
||||
void HandleRelayIntro (const uint8_t * buf, size_t len, int attempts = 0);
|
||||
void HandleRelayResponse (const uint8_t * buf, size_t len);
|
||||
|
|
Loading…
Reference in a new issue