|
|
@ -221,6 +221,7 @@ namespace transport |
|
|
|
m_IncompleteMessages.clear (); |
|
|
|
m_IncompleteMessages.clear (); |
|
|
|
m_RelaySessions.clear (); |
|
|
|
m_RelaySessions.clear (); |
|
|
|
m_PeerTests.clear (); |
|
|
|
m_PeerTests.clear (); |
|
|
|
|
|
|
|
m_ReceivedI2NPMsgIDs.clear (); |
|
|
|
m_Server.RemoveSession (m_SourceConnID); |
|
|
|
m_Server.RemoveSession (m_SourceConnID); |
|
|
|
transports.PeerDisconnected (shared_from_this ()); |
|
|
|
transports.PeerDisconnected (shared_from_this ()); |
|
|
|
LogPrint (eLogDebug, "SSU2: Session terminated"); |
|
|
|
LogPrint (eLogDebug, "SSU2: Session terminated"); |
|
|
@ -1450,7 +1451,7 @@ namespace transport |
|
|
|
nextMsg->len = nextMsg->offset + size + 7; // 7 more bytes for full I2NP header
|
|
|
|
nextMsg->len = nextMsg->offset + size + 7; // 7 more bytes for full I2NP header
|
|
|
|
memcpy (nextMsg->GetNTCP2Header (), buf + offset, size); |
|
|
|
memcpy (nextMsg->GetNTCP2Header (), buf + offset, size); |
|
|
|
nextMsg->FromNTCP2 (); // SSU2 has the same format as NTCP2
|
|
|
|
nextMsg->FromNTCP2 (); // SSU2 has the same format as NTCP2
|
|
|
|
m_Handler.PutNextMessage (std::move (nextMsg)); |
|
|
|
HandleI2NPMsg (std::move (nextMsg)); |
|
|
|
m_IsDataReceived = true; |
|
|
|
m_IsDataReceived = true; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -1738,7 +1739,7 @@ namespace transport |
|
|
|
{ |
|
|
|
{ |
|
|
|
// we have all follow-on fragments already
|
|
|
|
// we have all follow-on fragments already
|
|
|
|
m->msg->FromNTCP2 (); |
|
|
|
m->msg->FromNTCP2 (); |
|
|
|
m_Handler.PutNextMessage (std::move (m->msg)); |
|
|
|
HandleI2NPMsg (std::move (m->msg)); |
|
|
|
m_IncompleteMessages.erase (it); |
|
|
|
m_IncompleteMessages.erase (it); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1760,14 +1761,14 @@ namespace transport |
|
|
|
if (isLast) |
|
|
|
if (isLast) |
|
|
|
{ |
|
|
|
{ |
|
|
|
it->second->msg->FromNTCP2 (); |
|
|
|
it->second->msg->FromNTCP2 (); |
|
|
|
m_Handler.PutNextMessage (std::move (it->second->msg)); |
|
|
|
HandleI2NPMsg (std::move (it->second->msg)); |
|
|
|
m_IncompleteMessages.erase (it); |
|
|
|
m_IncompleteMessages.erase (it); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (ConcatOutOfSequenceFragments (it->second)) |
|
|
|
if (ConcatOutOfSequenceFragments (it->second)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
m_Handler.PutNextMessage (std::move (it->second->msg)); |
|
|
|
HandleI2NPMsg (std::move (it->second->msg)); |
|
|
|
m_IncompleteMessages.erase (it); |
|
|
|
m_IncompleteMessages.erase (it); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
@ -2268,6 +2269,25 @@ namespace transport |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SSU2Session::HandleI2NPMsg (std::shared_ptr<I2NPMessage>&& msg) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (!msg) return; |
|
|
|
|
|
|
|
int32_t msgID = msg->GetMsgID (); |
|
|
|
|
|
|
|
if (!m_ReceivedI2NPMsgIDs.count (msgID)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (!msg->IsExpired ()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// m_LastActivityTimestamp is updated in ProcessData before
|
|
|
|
|
|
|
|
m_ReceivedI2NPMsgIDs.emplace (msgID, (uint32_t)m_LastActivityTimestamp); |
|
|
|
|
|
|
|
m_Handler.PutNextMessage (std::move (msg)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
LogPrint (eLogDebug, "SSU2: Message ", msgID, " expired"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
LogPrint (eLogDebug, "SSU2: Message ", msgID, " already received"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool SSU2Session::ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep) |
|
|
|
bool SSU2Session::ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (size < 2) return false; |
|
|
|
if (size < 2) return false; |
|
|
@ -2790,6 +2810,20 @@ namespace transport |
|
|
|
else |
|
|
|
else |
|
|
|
++it; |
|
|
|
++it; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (m_ReceivedI2NPMsgIDs.size () > SSU2_MAX_NUM_RECEIVED_I2NP_MSGIDS || ts > m_LastActivityTimestamp + SSU2_DECAY_INTERVAL) |
|
|
|
|
|
|
|
// decay
|
|
|
|
|
|
|
|
m_ReceivedI2NPMsgIDs.clear (); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// delete old received msgIDs
|
|
|
|
|
|
|
|
for (auto it = m_ReceivedI2NPMsgIDs.begin (); it != m_ReceivedI2NPMsgIDs.end ();) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (ts > it->second + SSU2_RECEIVED_I2NP_MSGIDS_CLEANUP_TIMEOUT) |
|
|
|
|
|
|
|
it = m_ReceivedI2NPMsgIDs.erase (it); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
++it; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
if (!m_OutOfSequencePackets.empty ()) |
|
|
|
if (!m_OutOfSequencePackets.empty ()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (m_OutOfSequencePackets.size () > 2*SSU2_MAX_NUM_ACK_RANGES || |
|
|
|
if (m_OutOfSequencePackets.size () > 2*SSU2_MAX_NUM_ACK_RANGES || |
|
|
|