diff --git a/Garlic.cpp b/Garlic.cpp index b7d44d5e..35c8bc15 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -20,6 +20,7 @@ namespace garlic std::shared_ptr destination, int numTags, bool attachLeaseSet): m_Owner (owner), m_Destination (destination), m_NumTags (numTags), m_LeaseSetUpdateStatus (attachLeaseSet ? eLeaseSetUpdated : eLeaseSetDoNotSend), + m_LeaseSetUpdateMsgID (0), m_ElGamalEncryption (new i2p::crypto::ElGamalEncryption (destination->GetEncryptionPublicKey ())) { // create new session tags and session key @@ -28,7 +29,7 @@ namespace garlic } GarlicRoutingSession::GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag): - m_Owner (nullptr), m_Destination (nullptr), m_NumTags (1), m_LeaseSetUpdateStatus (eLeaseSetDoNotSend) + m_Owner (nullptr), m_Destination (nullptr), m_NumTags (1), m_LeaseSetUpdateStatus (eLeaseSetDoNotSend), m_LeaseSetUpdateMsgID (0) { memcpy (m_SessionKey, sessionKey, 32); m_Encryption.SetKey (m_SessionKey); @@ -83,6 +84,7 @@ namespace garlic if (msgID == m_LeaseSetUpdateMsgID) { m_LeaseSetUpdateStatus = eLeaseSetUpToDate; + m_LeaseSetUpdateMsgID = 0; LogPrint (eLogInfo, "Garlic: LeaseSet update confirmed"); } else @@ -117,7 +119,7 @@ namespace garlic bool GarlicRoutingSession::CleanupExpiredTags () { - uint32_t ts = i2p::util::GetSecondsSinceEpoch (); + auto ts = i2p::util::GetSecondsSinceEpoch (); for (auto it = m_SessionTags.begin (); it != m_SessionTags.end ();) { if (ts >= it->creationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT) @@ -126,6 +128,12 @@ namespace garlic ++it; } CleanupUnconfirmedTags (); + if (m_LeaseSetUpdateMsgID && ts*1000LL > m_LeaseSetSubmissionTime + LEASET_CONFIRMATION_TIMEOUT) + { + if (m_Owner) + m_Owner->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID); + m_LeaseSetUpdateMsgID = 0; + } return !m_SessionTags.empty () || !m_UnconfirmedTagsMsgs.empty (); } @@ -287,6 +295,7 @@ namespace garlic // attach LeaseSet if (m_LeaseSetUpdateStatus == eLeaseSetUpdated) { + if (m_LeaseSetUpdateMsgID) m_Owner->RemoveDeliveryStatusSession (m_LeaseSetUpdateMsgID); // remove previous m_LeaseSetUpdateStatus = eLeaseSetSubmitted; m_LeaseSetUpdateMsgID = msgID; m_LeaseSetSubmissionTime = ts; @@ -625,18 +634,29 @@ namespace garlic LogPrint (eLogDebug, "Garlic: ", numExpiredTags, " tags expired for ", GetIdentHash().ToBase64 ()); // outgoing - std::unique_lock l(m_SessionsMutex); - for (auto it = m_Sessions.begin (); it != m_Sessions.end ();) { - it->second->GetSharedRoutingPath (); // delete shared path if necessary - if (!it->second->CleanupExpiredTags ()) + std::unique_lock l(m_SessionsMutex); + for (auto it = m_Sessions.begin (); it != m_Sessions.end ();) { - LogPrint (eLogInfo, "Routing session to ", it->first.ToBase32 (), " deleted"); - it = m_Sessions.erase (it); + it->second->GetSharedRoutingPath (); // delete shared path if necessary + if (!it->second->CleanupExpiredTags ()) + { + LogPrint (eLogInfo, "Routing session to ", it->first.ToBase32 (), " deleted"); + it->second->SetOwner (nullptr); + it = m_Sessions.erase (it); + } + else + ++it; } + } + // delivery status sessions + for (auto it = m_DeliveryStatusSessions.begin (); it != m_DeliveryStatusSessions.end (); ) + { + if (it->second->GetOwner () != this) + it = m_DeliveryStatusSessions.erase (it); else ++it; - } + } } void GarlicDestination::RemoveDeliveryStatusSession (uint32_t msgID) diff --git a/Garlic.h b/Garlic.h index a3ab7d92..e0e65111 100644 --- a/Garlic.h +++ b/Garlic.h @@ -111,6 +111,9 @@ namespace garlic std::shared_ptr GetSharedRoutingPath (); void SetSharedRoutingPath (std::shared_ptr path); + const GarlicDestination * GetOwner () const { return m_Owner; } + void SetOwner (GarlicDestination * owner) { m_Owner = owner; } + private: size_t CreateAESBlock (uint8_t * buf, std::shared_ptr msg);