diff --git a/libi2pd/ECIESX25519AEADRatchetSession.h b/libi2pd/ECIESX25519AEADRatchetSession.h index cf4eb3d7..79e920b5 100644 --- a/libi2pd/ECIESX25519AEADRatchetSession.h +++ b/libi2pd/ECIESX25519AEADRatchetSession.h @@ -122,6 +122,8 @@ namespace garlic bool CheckExpired (uint64_t ts); // true is expired bool CanBeRestarted (uint64_t ts) const { return ts > m_LastActivityTimestamp + ECIESX25519_RESTART_TIMEOUT; } + bool IsRatchets () const { return true; }; + private: void ResetKeys (); diff --git a/libi2pd/Garlic.h b/libi2pd/Garlic.h index 2c71abe8..6c81dabf 100644 --- a/libi2pd/Garlic.h +++ b/libi2pd/Garlic.h @@ -105,6 +105,7 @@ namespace garlic virtual std::shared_ptr WrapSingleMessage (std::shared_ptr msg) = 0; virtual bool CleanupUnconfirmedTags () { return false; }; // for I2CP, override in ElGamalAESSession virtual bool MessageConfirmed (uint32_t msgID); + virtual bool IsRatchets () const { return false; }; void SetLeaseSetUpdated () { diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 0e7c245e..933fa707 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -39,14 +39,14 @@ namespace i2p return (len < I2NP_MAX_SHORT_MESSAGE_SIZE - I2NP_HEADER_SIZE - 2) ? NewI2NPShortMessage () : NewI2NPMessage (); } - void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID) + void I2NPMessage::FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID, bool checksum) { SetTypeID (msgType); if (!replyMsgID) RAND_bytes ((uint8_t *)&replyMsgID, 4); SetMsgID (replyMsgID); SetExpiration (i2p::util::GetMillisecondsSinceEpoch () + I2NP_MESSAGE_EXPIRATION_TIMEOUT); UpdateSize (); - UpdateChks (); + if (checksum) UpdateChks (); } void I2NPMessage::RenewI2NPMessageHeader () diff --git a/libi2pd/I2NPProtocol.h b/libi2pd/I2NPProtocol.h index 2fca1538..c8957b5f 100644 --- a/libi2pd/I2NPProtocol.h +++ b/libi2pd/I2NPProtocol.h @@ -218,7 +218,7 @@ namespace tunnel memcpy (ntcp2 + I2NP_HEADER_TYPEID_OFFSET, GetHeader () + I2NP_HEADER_TYPEID_OFFSET, 5); // typeid + msgid } - void FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID = 0); + void FillI2NPMessageHeader (I2NPMessageType msgType, uint32_t replyMsgID = 0, bool checksum = true); void RenewI2NPMessageHeader (); bool IsExpired () const; }; diff --git a/libi2pd/Streaming.cpp b/libi2pd/Streaming.cpp index 3214e81b..6b547170 100644 --- a/libi2pd/Streaming.cpp +++ b/libi2pd/Streaming.cpp @@ -756,7 +756,8 @@ namespace stream std::vector msgs; for (auto it: packets) { - auto msg = m_RoutingSession->WrapSingleMessage (m_LocalDestination.CreateDataMessage (it->GetBuffer (), it->GetLength (), m_Port)); + auto msg = m_RoutingSession->WrapSingleMessage (m_LocalDestination.CreateDataMessage ( + it->GetBuffer (), it->GetLength (), m_Port, !m_RoutingSession->IsRatchets ())); msgs.push_back (i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeTunnel, @@ -1207,9 +1208,10 @@ namespace stream DeletePacket (uncompressed); } - std::shared_ptr StreamingDestination::CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort) + std::shared_ptr StreamingDestination::CreateDataMessage ( + const uint8_t * payload, size_t len, uint16_t toPort, bool checksum) { - auto msg = NewI2NPShortMessage (); + auto msg = m_I2NPMsgsPool.AcquireShared (); if (!m_Gzip || len <= i2p::stream::COMPRESSION_THRESHOLD_SIZE) m_Deflator.SetCompressionLevel (Z_NO_COMPRESSION); else @@ -1225,7 +1227,7 @@ namespace stream htobe16buf (buf + 6, toPort); // destination port buf[9] = i2p::client::PROTOCOL_TYPE_STREAMING; // streaming protocol msg->len += size; - msg->FillI2NPMessageHeader (eI2NPData); + msg->FillI2NPMessageHeader (eI2NPData, 0, checksum); } else msg = nullptr; diff --git a/libi2pd/Streaming.h b/libi2pd/Streaming.h index 985a7eca..64e4c18d 100644 --- a/libi2pd/Streaming.h +++ b/libi2pd/Streaming.h @@ -255,20 +255,18 @@ namespace stream void ResetAcceptor (); bool IsAcceptorSet () const { return m_Acceptor != nullptr; }; void AcceptOnce (const Acceptor& acceptor); + void AcceptOnceAcceptor (std::shared_ptr stream, Acceptor acceptor, Acceptor prev); std::shared_ptr GetOwner () const { return m_Owner; }; void SetOwner (std::shared_ptr owner) { m_Owner = owner; }; uint16_t GetLocalPort () const { return m_LocalPort; }; void HandleDataMessagePayload (const uint8_t * buf, size_t len); - std::shared_ptr CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort); + std::shared_ptr CreateDataMessage (const uint8_t * payload, size_t len, uint16_t toPort, bool checksum = true); Packet * NewPacket () { return m_PacketsPool.Acquire(); } void DeletePacket (Packet * p) { return m_PacketsPool.Release(p); } - - void AcceptOnceAcceptor (std::shared_ptr stream, Acceptor acceptor, Acceptor prev); - private: void HandleNextPacket (Packet * packet); @@ -289,6 +287,7 @@ namespace stream std::map > m_SavedPackets; // receiveStreamID->packets, arrived before SYN i2p::util::MemoryPool m_PacketsPool; + i2p::util::MemoryPool > m_I2NPMsgsPool; public: