diff --git a/Garlic.cpp b/Garlic.cpp index ef894b67..ad33b38d 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -15,7 +15,7 @@ namespace i2p namespace garlic { GarlicRoutingSession::GarlicRoutingSession (const i2p::data::RoutingDestination * destination, int numTags): - m_Destination (destination), m_FirstMsgID (0), m_IsAcknowledged (false), m_NumTags (numTags), + m_Destination (destination), m_IsAcknowledged (false), m_NumTags (numTags), m_NextTag (-1), m_SessionTags (0), m_TagsCreationTime (0), m_LocalLeaseSet (nullptr) { // create new session tags and session key @@ -31,7 +31,7 @@ namespace garlic } GarlicRoutingSession::GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag): - m_Destination (nullptr), m_FirstMsgID (0), m_IsAcknowledged (true), m_NumTags (1), m_NextTag (0), + m_Destination (nullptr), m_IsAcknowledged (true), m_NumTags (1), m_NextTag (0), m_LocalLeaseSet (nullptr) { memcpy (m_SessionKey, sessionKey, 32); @@ -175,7 +175,7 @@ namespace garlic if (size > 0) // successive? { (*numCloves)++; - m_FirstMsgID = msgID; + routing.DeliveryStatusSent (this, msgID); } else LogPrint ("DeliveryStatus clove was not created"); @@ -292,14 +292,9 @@ namespace garlic decryption->SetTagCount (1); m_SessionTags[SessionTag(tag)] = decryption; } - - I2NPMessage * GarlicRouting::WrapSingleMessage (const i2p::data::RoutingDestination& destination, I2NPMessage * msg) - { - return WrapMessage (destination, msg, nullptr); - } - I2NPMessage * GarlicRouting::WrapMessage (const i2p::data::RoutingDestination& destination, - I2NPMessage * msg, const i2p::data::LeaseSet * leaseSet) + GarlicRoutingSession * GarlicRouting::GetRoutingSession ( + const i2p::data::RoutingDestination& destination, int numTags) { auto it = m_Sessions.find (destination.GetIdentHash ()); GarlicRoutingSession * session = nullptr; @@ -307,19 +302,30 @@ namespace garlic session = it->second; if (!session) { - session = new GarlicRoutingSession (&destination, 32); + session = new GarlicRoutingSession (&destination, numTags); std::unique_lock l(m_SessionsMutex); m_Sessions[destination.GetIdentHash ()] = session; } + return session; + } + + I2NPMessage * GarlicRouting::WrapSingleMessage (const i2p::data::RoutingDestination& destination, I2NPMessage * msg) + { + return WrapMessage (destination, msg, nullptr); + } - I2NPMessage * ret = session->WrapSingleMessage (msg, leaseSet); - if (!session->GetNextTag ()) // tags have beed recreated - { - std::unique_lock l(m_SessionsMutex); - m_CreatedSessions[session->GetFirstMsgID ()] = session; - } - return ret; + I2NPMessage * GarlicRouting::WrapMessage (const i2p::data::RoutingDestination& destination, + I2NPMessage * msg, const i2p::data::LeaseSet * leaseSet) + { + auto session = GetRoutingSession (destination, leaseSet ? 32 : 0); // don't use tag if no LeaseSet + return session->WrapSingleMessage (msg, leaseSet); } + + void GarlicRouting::DeliveryStatusSent (GarlicRoutingSession * session, uint32_t msgID) + { + std::unique_lock l(m_SessionsMutex); + m_CreatedSessions[msgID] = session; + } void GarlicRouting::HandleGarlicMessage (I2NPMessage * msg) { diff --git a/Garlic.h b/Garlic.h index c120ae37..f66585a6 100644 --- a/Garlic.h +++ b/Garlic.h @@ -48,7 +48,6 @@ namespace garlic ~GarlicRoutingSession (); I2NPMessage * WrapSingleMessage (I2NPMessage * msg, const i2p::data::LeaseSet * leaseSet); int GetNextTag () const { return m_NextTag; }; - uint32_t GetFirstMsgID () const { return m_FirstMsgID; }; bool IsAcknowledged () const { return m_IsAcknowledged; }; void SetAcknowledged (bool acknowledged) { m_IsAcknowledged = acknowledged; }; @@ -66,7 +65,6 @@ namespace garlic const i2p::data::RoutingDestination * m_Destination; uint8_t m_SessionKey[32]; - uint32_t m_FirstMsgID; // first message ID bool m_IsAcknowledged; int m_NumTags, m_NextTag; SessionTag * m_SessionTags; // m_NumTags*32 bytes @@ -104,10 +102,13 @@ namespace garlic void PostI2NPMsg (I2NPMessage * msg); void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag + GarlicRoutingSession * GetRoutingSession (const i2p::data::RoutingDestination& destination, int numTags); I2NPMessage * WrapSingleMessage (const i2p::data::RoutingDestination& destination, I2NPMessage * msg); I2NPMessage * WrapMessage (const i2p::data::RoutingDestination& destination, I2NPMessage * msg, const i2p::data::LeaseSet * leaseSet = nullptr); + void DeliveryStatusSent (GarlicRoutingSession * session, uint32_t msgID); + private: void Run (); diff --git a/Streaming.cpp b/Streaming.cpp index e5205313..a51b6909 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -9,7 +9,6 @@ #include "Tunnel.h" #include "Timestamp.h" #include "CryptoConst.h" -#include "Garlic.h" #include "NetDb.h" #include "Streaming.h" @@ -20,8 +19,8 @@ namespace stream Stream::Stream (boost::asio::io_service& service, StreamingDestination * local, const i2p::data::LeaseSet& remote): m_Service (service), m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1), m_IsOpen (false), - m_LeaseSetUpdated (true), m_LocalDestination (local), - m_RemoteLeaseSet (&remote), m_CurrentOutboundTunnel (nullptr), + m_LeaseSetUpdated (true), m_LocalDestination (local), m_RemoteLeaseSet (&remote), + m_RoutingSession (nullptr), m_CurrentOutboundTunnel (nullptr), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service) { m_RecvStreamID = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (); @@ -31,7 +30,7 @@ namespace stream Stream::Stream (boost::asio::io_service& service, StreamingDestination * local): m_Service (service), m_SendStreamID (0), m_SequenceNumber (0), m_LastReceivedSequenceNumber (-1), m_IsOpen (false), m_LeaseSetUpdated (true), m_LocalDestination (local), - m_RemoteLeaseSet (nullptr), m_CurrentOutboundTunnel (nullptr), + m_RemoteLeaseSet (nullptr), m_RoutingSession (nullptr), m_CurrentOutboundTunnel (nullptr), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service) { m_RecvStreamID = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (); @@ -427,8 +426,9 @@ namespace stream std::vector msgs; for (auto it: packets) { - auto msg = i2p::garlic::routing.WrapMessage (*m_RemoteLeaseSet, - CreateDataMessage (this, it->GetBuffer (), it->GetLength ()), leaseSet); + auto msg = m_RoutingSession->WrapSingleMessage ( + CreateDataMessage (this, it->GetBuffer (), it->GetLength ()), + leaseSet); msgs.push_back (i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeTunnel, @@ -486,11 +486,13 @@ namespace stream if (!m_RemoteLeaseSet) { m_RemoteLeaseSet = i2p::data::netdb.FindLeaseSet (m_RemoteIdentity.GetIdentHash ()); - if (!m_RemoteLeaseSet) + if (!m_RemoteLeaseSet) LogPrint ("LeaseSet ", m_RemoteIdentity.GetIdentHash ().ToBase64 (), " not found"); } if (m_RemoteLeaseSet) { + if (!m_RoutingSession) + m_RoutingSession = i2p::garlic::routing.GetRoutingSession (*m_RemoteLeaseSet, 32); auto leases = m_RemoteLeaseSet->GetNonExpiredLeases (); if (!leases.empty ()) { diff --git a/Streaming.h b/Streaming.h index c0dbd5e9..5b8ad08a 100644 --- a/Streaming.h +++ b/Streaming.h @@ -16,6 +16,7 @@ #include "LeaseSet.h" #include "I2NPProtocol.h" #include "TunnelPool.h" +#include "Garlic.h" namespace i2p { @@ -127,6 +128,7 @@ namespace stream StreamingDestination * m_LocalDestination; i2p::data::IdentityEx m_RemoteIdentity; const i2p::data::LeaseSet * m_RemoteLeaseSet; + i2p::garlic::GarlicRoutingSession * m_RoutingSession; i2p::data::Lease m_CurrentRemoteLease; i2p::tunnel::OutboundTunnel * m_CurrentOutboundTunnel; std::queue m_ReceiveQueue;