diff --git a/SSUData.cpp b/SSUData.cpp index a1b8163b..db71edb7 100644 --- a/SSUData.cpp +++ b/SSUData.cpp @@ -19,8 +19,27 @@ namespace ssu DeleteI2NPMessage (it.second->msg); delete it.second; } + for (auto it: m_SentMessages) + { + for (auto f: it.second) + delete[] f; + } } + void SSUData::ProcessSentMessageAck (uint32_t msgID) + { + auto it = m_SentMessages.find (msgID); + if (it != m_SentMessages.end ()) + { + // delete all ack-ed message's fragments + for (auto f: it->second) + delete[] f; + m_SentMessages.erase (it); + } + else + LogPrint ("SSU ack received for unknown message ", msgID); + } + void SSUData::ProcessMessage (uint8_t * buf, size_t len) { //uint8_t * start = buf; @@ -32,7 +51,8 @@ namespace ssu // explicit ACKs uint8_t numAcks =*buf; buf++; - // TODO: process ACKs + for (int i = 0; i < numAcks; i++) + ProcessSentMessageAck (be32toh (((uint32_t *)buf)[i])); buf += numAcks*4; } if (flag & DATA_FLAG_ACK_BITFIELDS_INCLUDED) @@ -42,8 +62,9 @@ namespace ssu buf++; for (int i = 0; i < numBitfields; i++) { + ProcessSentMessageAck (be32toh (*(uint32_t *)buf)); // TODO: should be replaced to fragments buf += 4; // msgID - // TODO: process ACH bitfields + // TODO: process individual Ack bitfields while (*buf & 0x80) // not last buf++; buf++; // last byte @@ -137,7 +158,9 @@ namespace ssu void SSUData::Send (i2p::I2NPMessage * msg) { - uint32_t msgID = htobe32 (msg->ToSSU ()); + uint32_t msgID = msg->ToSSU (); + auto fragments = m_SentMessages[msgID]; + msgID = htobe32 (msgID); size_t payloadSize = SSU_MTU - sizeof (SSUHeader) - 9; // 9 = flag + #frg(1) + messageID(4) + frag info (3) size_t len = msg->GetLength (); uint8_t * msgBuf = msg->GetSSUHeader (); @@ -145,7 +168,9 @@ namespace ssu uint32_t fragmentNum = 0; while (len > 0) { - uint8_t buf[SSU_MTU + 18], * payload = buf + sizeof (SSUHeader); + uint8_t * buf = new uint8_t[SSU_MTU + 18]; + fragments.push_back (buf); + uint8_t * payload = buf + sizeof (SSUHeader); *payload = DATA_FLAG_WANT_REPLY; // for compatibility payload++; *payload = 1; // always 1 message fragment per message diff --git a/SSUData.h b/SSUData.h index 71273dc2..4829aa56 100644 --- a/SSUData.h +++ b/SSUData.h @@ -3,6 +3,7 @@ #include #include +#include #include "I2NPProtocol.h" namespace i2p @@ -32,6 +33,7 @@ namespace ssu private: void SendMsgAck (uint32_t msgID); + void ProcessSentMessageAck (uint32_t msgID); private: @@ -45,6 +47,7 @@ namespace ssu SSUSession& m_Session; std::map m_IncomleteMessages; + std::map > m_SentMessages; // msgID -> fragments }; } }