|
|
@ -23,10 +23,6 @@ namespace transport |
|
|
|
|
|
|
|
|
|
|
|
SSUData::~SSUData () |
|
|
|
SSUData::~SSUData () |
|
|
|
{ |
|
|
|
{ |
|
|
|
for (auto it: m_IncomleteMessages) |
|
|
|
|
|
|
|
delete it.second; |
|
|
|
|
|
|
|
for (auto it: m_SentMessages) |
|
|
|
|
|
|
|
delete it.second; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SSUData::Start () |
|
|
|
void SSUData::Start () |
|
|
@ -78,7 +74,6 @@ namespace transport |
|
|
|
auto it = m_SentMessages.find (msgID); |
|
|
|
auto it = m_SentMessages.find (msgID); |
|
|
|
if (it != m_SentMessages.end ()) |
|
|
|
if (it != m_SentMessages.end ()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
delete it->second; |
|
|
|
|
|
|
|
m_SentMessages.erase (it); |
|
|
|
m_SentMessages.erase (it); |
|
|
|
if (m_SentMessages.empty ()) |
|
|
|
if (m_SentMessages.empty ()) |
|
|
|
m_ResendTimer.cancel (); |
|
|
|
m_ResendTimer.cancel (); |
|
|
@ -161,22 +156,19 @@ namespace transport |
|
|
|
|
|
|
|
|
|
|
|
// find message with msgID
|
|
|
|
// find message with msgID
|
|
|
|
I2NPMessage * msg = nullptr; |
|
|
|
I2NPMessage * msg = nullptr; |
|
|
|
IncompleteMessage * incompleteMessage = nullptr; |
|
|
|
auto it = m_IncompleteMessages.find (msgID); |
|
|
|
auto it = m_IncomleteMessages.find (msgID); |
|
|
|
if (it != m_IncompleteMessages.end ()) |
|
|
|
if (it != m_IncomleteMessages.end ()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// message exists
|
|
|
|
// message exists
|
|
|
|
incompleteMessage = it->second; |
|
|
|
msg = it->second->msg; |
|
|
|
msg = incompleteMessage->msg; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
// create new message
|
|
|
|
// create new message
|
|
|
|
msg = NewI2NPMessage (); |
|
|
|
msg = NewI2NPMessage (); |
|
|
|
msg->len -= I2NP_SHORT_HEADER_SIZE; |
|
|
|
msg->len -= I2NP_SHORT_HEADER_SIZE; |
|
|
|
incompleteMessage = new IncompleteMessage (msg); |
|
|
|
it = m_IncompleteMessages.insert (std::make_pair (msgID, |
|
|
|
m_IncomleteMessages[msgID] = incompleteMessage; |
|
|
|
std::unique_ptr<IncompleteMessage>(new IncompleteMessage (msg)))).first; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
std::unique_ptr<IncompleteMessage>& incompleteMessage = it->second; |
|
|
|
|
|
|
|
|
|
|
|
// handle current fragment
|
|
|
|
// handle current fragment
|
|
|
|
if (fragmentNum == incompleteMessage->nextFragmentNum) |
|
|
|
if (fragmentNum == incompleteMessage->nextFragmentNum) |
|
|
@ -228,8 +220,7 @@ namespace transport |
|
|
|
{ |
|
|
|
{ |
|
|
|
// delete incomplete message
|
|
|
|
// delete incomplete message
|
|
|
|
incompleteMessage->msg = nullptr; |
|
|
|
incompleteMessage->msg = nullptr; |
|
|
|
delete incompleteMessage; |
|
|
|
m_IncompleteMessages.erase (msgID); |
|
|
|
m_IncomleteMessages.erase (msgID); |
|
|
|
|
|
|
|
// process message
|
|
|
|
// process message
|
|
|
|
SendMsgAck (msgID); |
|
|
|
SendMsgAck (msgID); |
|
|
|
msg->FromSSU (msgID); |
|
|
|
msg->FromSSU (msgID); |
|
|
@ -303,10 +294,14 @@ namespace transport |
|
|
|
} |
|
|
|
} |
|
|
|
if (m_SentMessages.empty ()) // schedule resend at first message only
|
|
|
|
if (m_SentMessages.empty ()) // schedule resend at first message only
|
|
|
|
ScheduleResend (); |
|
|
|
ScheduleResend (); |
|
|
|
SentMessage * sentMessage = new SentMessage; |
|
|
|
|
|
|
|
m_SentMessages[msgID] = sentMessage; |
|
|
|
auto ret = m_SentMessages.insert (std::make_pair (msgID, std::unique_ptr<SentMessage>(new SentMessage))); |
|
|
|
|
|
|
|
std::unique_ptr<SentMessage>& sentMessage = ret.first->second; |
|
|
|
|
|
|
|
if (ret.second) |
|
|
|
|
|
|
|
{ |
|
|
|
sentMessage->nextResendTime = i2p::util::GetSecondsSinceEpoch () + RESEND_INTERVAL; |
|
|
|
sentMessage->nextResendTime = i2p::util::GetSecondsSinceEpoch () + RESEND_INTERVAL; |
|
|
|
sentMessage->numResends = 0; |
|
|
|
sentMessage->numResends = 0; |
|
|
|
|
|
|
|
} |
|
|
|
auto& fragments = sentMessage->fragments; |
|
|
|
auto& fragments = sentMessage->fragments; |
|
|
|
size_t payloadSize = m_PacketSize - sizeof (SSUHeader) - 9; // 9 = flag + #frg(1) + messageID(4) + frag info (3)
|
|
|
|
size_t payloadSize = m_PacketSize - sizeof (SSUHeader) - 9; // 9 = flag + #frg(1) + messageID(4) + frag info (3)
|
|
|
|
size_t len = msg->GetLength (); |
|
|
|
size_t len = msg->GetLength (); |
|
|
@ -451,7 +446,6 @@ namespace transport |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint (eLogError, "SSU message has not been ACKed after ", MAX_NUM_RESENDS, " attempts. Deleted"); |
|
|
|
LogPrint (eLogError, "SSU message has not been ACKed after ", MAX_NUM_RESENDS, " attempts. Deleted"); |
|
|
|
delete it->second; |
|
|
|
|
|
|
|
it = m_SentMessages.erase (it); |
|
|
|
it = m_SentMessages.erase (it); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -491,13 +485,12 @@ namespace transport |
|
|
|
if (ecode != boost::asio::error::operation_aborted) |
|
|
|
if (ecode != boost::asio::error::operation_aborted) |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch (); |
|
|
|
uint32_t ts = i2p::util::GetSecondsSinceEpoch (); |
|
|
|
for (auto it = m_IncomleteMessages.begin (); it != m_IncomleteMessages.end ();) |
|
|
|
for (auto it = m_IncompleteMessages.begin (); it != m_IncompleteMessages.end ();) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (ts > it->second->lastFragmentInsertTime + INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT) |
|
|
|
if (ts > it->second->lastFragmentInsertTime + INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint (eLogError, "SSU message ", it->first, " was not completed in ", INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT, " seconds. Deleted"); |
|
|
|
LogPrint (eLogError, "SSU message ", it->first, " was not completed in ", INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT, " seconds. Deleted"); |
|
|
|
delete it->second; |
|
|
|
it = m_IncompleteMessages.erase (it); |
|
|
|
it = m_IncomleteMessages.erase (it); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
it++; |
|
|
|
it++; |
|
|
|