diff --git a/I2NPProtocol.h b/I2NPProtocol.h index 7f47601e..3905da5b 100644 --- a/I2NPProtocol.h +++ b/I2NPProtocol.h @@ -4,6 +4,7 @@ #include #include #include +#include "I2PEndian.h" #include "RouterInfo.h" namespace i2p @@ -19,6 +20,12 @@ namespace i2p uint8_t chks; }; + struct I2NPHeaderShort + { + uint8_t typeID; + uint32_t shortExpiration; + }; + struct I2NPDatabaseStoreMsg { uint8_t key[32]; @@ -101,6 +108,19 @@ namespace i2p len = offset + other.GetLength (); return *this; } + + // for SSU only + uint8_t * GetSSUHeader () { return buf + offset + sizeof(I2NPHeader) - sizeof(I2NPHeaderShort); }; + void FromSSU (uint32_t msgID) // we have received SSU message and convert it to regular + { + I2NPHeaderShort ssu = *(I2NPHeaderShort *)GetSSUHeader (); + I2NPHeader * header = GetHeader (); + header->typeID = ssu.typeID; + header->msgID = htobe32 (msgID); + header->expiration = htobe64 (be32toh (ssu.shortExpiration)*1000LL); + header->size = htobe16 (len - offset - sizeof (I2NPHeader)); + header->chks = 0; + } }; I2NPMessage * NewI2NPMessage (); void DeleteI2NPMessage (I2NPMessage * msg); diff --git a/SSU.cpp b/SSU.cpp index 4fbd2696..ea7368bc 100644 --- a/SSU.cpp +++ b/SSU.cpp @@ -388,23 +388,31 @@ namespace ssu { auto it = m_IncomleteMessages.find (msgID); if (it != m_IncomleteMessages.end ()) + { msg = it->second; + memcpy (msg->buf + msg->len, buf, fragmentSize); + msg->len += fragmentSize; + } else // TODO: LogPrint ("Unexpected follow-on fragment ", fragmentNum, " of message ", msgID); } else // first fragment + { msg = NewI2NPMessage (); + memcpy (msg->GetSSUHeader (), buf, fragmentSize); + msg->len += fragmentSize - sizeof (I2NPHeaderShort); + } + if (msg) - { - memcpy (msg->buf + msg->len, buf, fragmentSize); - msg->len += fragmentSize; + { if (!fragmentNum && !isLast) m_IncomleteMessages[msgID] = msg; if (isLast) { if (fragmentNum > 0) m_IncomleteMessages.erase (msgID); + msg->FromSSU (msgID); i2p::HandleI2NPMessage (msg, false); } }