mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 12:24:19 +00:00
store out of sequence packet numbers
This commit is contained in:
parent
064b8042a5
commit
dd774b8dfd
@ -580,18 +580,16 @@ namespace transport
|
|||||||
LogPrint (eLogWarning, "SSU2: Data AEAD verification failed ");
|
LogPrint (eLogWarning, "SSU2: Data AEAD verification failed ");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HandlePayload (payload, payloadSize);
|
|
||||||
m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
|
m_LastActivityTimestamp = i2p::util::GetSecondsSinceEpoch ();
|
||||||
m_NumReceivedBytes += len;
|
m_NumReceivedBytes += len;
|
||||||
if (packetNum > m_ReceivePacketNum)
|
UpdateReceivePacketNum (packetNum);
|
||||||
{
|
if (HandlePayload (payload, payloadSize))
|
||||||
m_ReceivePacketNum = packetNum;
|
|
||||||
SendQuickAck (); // TODO: don't send too requently
|
SendQuickAck (); // TODO: don't send too requently
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSU2Session::HandlePayload (const uint8_t * buf, size_t len)
|
bool SSU2Session::HandlePayload (const uint8_t * buf, size_t len)
|
||||||
{
|
{
|
||||||
|
bool isData = false;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
while (offset < len)
|
while (offset < len)
|
||||||
{
|
{
|
||||||
@ -630,11 +628,14 @@ namespace transport
|
|||||||
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));
|
m_Handler.PutNextMessage (std::move (nextMsg));
|
||||||
|
isData = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case eSSU2BlkFirstFragment:
|
case eSSU2BlkFirstFragment:
|
||||||
|
isData = true;
|
||||||
break;
|
break;
|
||||||
case eSSU2BlkFollowOnFragment:
|
case eSSU2BlkFollowOnFragment:
|
||||||
|
isData = true;
|
||||||
break;
|
break;
|
||||||
case eSSU2BlkTermination:
|
case eSSU2BlkTermination:
|
||||||
LogPrint (eLogDebug, "SSU2: Termination");
|
LogPrint (eLogDebug, "SSU2: Termination");
|
||||||
@ -688,6 +689,7 @@ namespace transport
|
|||||||
offset += size;
|
offset += size;
|
||||||
}
|
}
|
||||||
m_Handler.Flush ();
|
m_Handler.Flush ();
|
||||||
|
return isData;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -744,9 +746,14 @@ namespace transport
|
|||||||
{
|
{
|
||||||
if (len < 8) return 0;
|
if (len < 8) return 0;
|
||||||
buf[0] = eSSU2BlkAck;
|
buf[0] = eSSU2BlkAck;
|
||||||
|
uint32_t ackThrough = m_OutOfSequencePackets.empty () ? m_ReceivePacketNum : *m_OutOfSequencePackets.rbegin ();
|
||||||
htobe16buf (buf + 1, 5);
|
htobe16buf (buf + 1, 5);
|
||||||
htobe32buf (buf + 3, m_ReceivePacketNum); // Ack Through
|
htobe32buf (buf + 3, ackThrough); // Ack Through
|
||||||
buf[7] = 0; // acnt
|
uint8_t acnt = 0;
|
||||||
|
if (ackThrough)
|
||||||
|
acnt = std::min ((int)ackThrough - 1, 255);
|
||||||
|
buf[7] = acnt; // acnt
|
||||||
|
// TODO: ranges
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,6 +800,27 @@ namespace transport
|
|||||||
htole64buf (nonce + 4, seqn);
|
htole64buf (nonce + 4, seqn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SSU2Session::UpdateReceivePacketNum (uint32_t packetNum)
|
||||||
|
{
|
||||||
|
if (packetNum <= m_ReceivePacketNum) return; // duplicate
|
||||||
|
if (packetNum == m_ReceivePacketNum + 1)
|
||||||
|
{
|
||||||
|
for (auto it = m_OutOfSequencePackets.begin (); it != m_OutOfSequencePackets.end ();)
|
||||||
|
{
|
||||||
|
if (*it == packetNum + 1)
|
||||||
|
{
|
||||||
|
packetNum++;
|
||||||
|
it = m_OutOfSequencePackets.erase (it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_ReceivePacketNum = packetNum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_OutOfSequencePackets.insert (packetNum);
|
||||||
|
}
|
||||||
|
|
||||||
void SSU2Session::SendQuickAck ()
|
void SSU2Session::SendQuickAck ()
|
||||||
{
|
{
|
||||||
uint8_t payload[SSU2_MTU];
|
uint8_t payload[SSU2_MTU];
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
@ -134,10 +135,11 @@ namespace transport
|
|||||||
void SendQuickAck ();
|
void SendQuickAck ();
|
||||||
void SendTermination ();
|
void SendTermination ();
|
||||||
|
|
||||||
void HandlePayload (const uint8_t * buf, size_t len);
|
bool HandlePayload (const uint8_t * buf, size_t len); // returns true is contains data
|
||||||
bool ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep);
|
bool ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep);
|
||||||
std::shared_ptr<const i2p::data::RouterInfo> ExtractRouterInfo (const uint8_t * buf, size_t size);
|
std::shared_ptr<const i2p::data::RouterInfo> ExtractRouterInfo (const uint8_t * buf, size_t size);
|
||||||
void CreateNonce (uint64_t seqn, uint8_t * nonce);
|
void CreateNonce (uint64_t seqn, uint8_t * nonce);
|
||||||
|
void UpdateReceivePacketNum (uint32_t packetNum); // for Ack
|
||||||
|
|
||||||
size_t CreateAddressBlock (const boost::asio::ip::udp::endpoint& ep, uint8_t * buf, size_t len);
|
size_t CreateAddressBlock (const boost::asio::ip::udp::endpoint& ep, uint8_t * buf, size_t len);
|
||||||
size_t CreateAckBlock (uint8_t * buf, size_t len);
|
size_t CreateAckBlock (uint8_t * buf, size_t len);
|
||||||
@ -154,6 +156,7 @@ namespace transport
|
|||||||
SSU2SessionState m_State;
|
SSU2SessionState m_State;
|
||||||
uint8_t m_KeyDataSend[64], m_KeyDataReceive[64];
|
uint8_t m_KeyDataSend[64], m_KeyDataReceive[64];
|
||||||
uint32_t m_SendPacketNum, m_ReceivePacketNum;
|
uint32_t m_SendPacketNum, m_ReceivePacketNum;
|
||||||
|
std::set<uint32_t> m_OutOfSequencePackets; // packet nums > receive packet num
|
||||||
i2p::I2NPMessagesHandler m_Handler;
|
i2p::I2NPMessagesHandler m_Handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user