From 18deb8b4f2885edcb4af3409377b4a31f4e863a3 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 22 Mar 2015 14:59:27 -0400 Subject: [PATCH] DeliveryStatus for LeaseSet --- Garlic.cpp | 41 +++++++++++++++++++++++++++++++---------- Garlic.h | 22 +++++++++++++++++----- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/Garlic.cpp b/Garlic.cpp index 53281fa2..87c7ae2a 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -17,7 +17,7 @@ namespace garlic GarlicRoutingSession::GarlicRoutingSession (GarlicDestination * owner, std::shared_ptr destination, int numTags): m_Owner (owner), m_Destination (destination), m_NumTags (numTags), - m_LeaseSetUpdated (numTags > 0) + m_LeaseSetUpdateStatus (numTags > 0 ? eLeaseSetUpdated : eLeaseSetUpToDate) { // create new session tags and session key m_Rnd.GenerateBlock (m_SessionKey, 32); @@ -25,7 +25,7 @@ namespace garlic } GarlicRoutingSession::GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag): - m_Owner (nullptr), m_Destination (nullptr), m_NumTags (1), m_LeaseSetUpdated (false) + m_Owner (nullptr), m_Destination (nullptr), m_NumTags (1), m_LeaseSetUpdateStatus (eLeaseSetUpToDate) { memcpy (m_SessionKey, sessionKey, 32); m_Encryption.SetKey (m_SessionKey); @@ -51,13 +51,25 @@ namespace garlic } return tags; } - + + void GarlicRoutingSession::MessageConfirmed (uint32_t msgID) + { + TagsConfirmed (msgID); + if (msgID == m_LeaseSetUpdateMsgID) + { + m_LeaseSetUpdateStatus = eLeaseSetUpToDate; + LogPrint (eLogInfo, "LeaseSet update confirmed"); + } + else + CleanupExpiredTags (); + } + void GarlicRoutingSession::TagsConfirmed (uint32_t msgID) { - uint32_t ts = i2p::util::GetSecondsSinceEpoch (); auto it = m_UnconfirmedTagsMsgs.find (msgID); if (it != m_UnconfirmedTagsMsgs.end ()) { + uint32_t ts = i2p::util::GetSecondsSinceEpoch (); UnconfirmedTags * tags = it->second; if (ts < tags->tagsCreationTime + OUTGOING_TAGS_EXPIRATION_TIMEOUT) { @@ -67,7 +79,6 @@ namespace garlic m_UnconfirmedTagsMsgs.erase (it); delete tags; } - CleanupExpiredTags (); } bool GarlicRoutingSession::CleanupExpiredTags () @@ -205,22 +216,32 @@ namespace garlic if (m_Owner) { - if (newTags) // new session + // resubmit non-confirmed LeaseSet + if (m_LeaseSetUpdateStatus == eLeaseSetSubmitted && + i2p::util::GetMillisecondsSinceEpoch () > m_LeaseSetSubmissionTime + LEASET_CONFIRMATION_TIMEOUT) + m_LeaseSetUpdateStatus = eLeaseSetUpdated; + + // attach DeviveryStatus if necessary + if (newTags || m_LeaseSetUpdateStatus == eLeaseSetUpdated) // new tags created or leaseset updated { // clove is DeliveryStatus size += CreateDeliveryStatusClove (payload + size, msgID); if (size > 0) // successive? { (*numCloves)++; - m_UnconfirmedTagsMsgs[msgID] = newTags; + if (newTags) // new tags created + m_UnconfirmedTagsMsgs[msgID] = newTags; m_Owner->DeliveryStatusSent (shared_from_this (), msgID); } else LogPrint ("DeliveryStatus clove was not created"); } - if (m_LeaseSetUpdated) + // attach LeaseSet + if (m_LeaseSetUpdateStatus == eLeaseSetUpdated) { - m_LeaseSetUpdated = false; + m_LeaseSetUpdateStatus = eLeaseSetSubmitted; + m_LeaseSetUpdateMsgID = msgID; + m_LeaseSetSubmissionTime = i2p::util::GetMillisecondsSinceEpoch (); // clove if our leaseSet must be attached auto leaseSet = CreateDatabaseStoreMsg (m_Owner->GetLeaseSet ()); size += CreateGarlicClove (payload + size, leaseSet, false); @@ -564,7 +585,7 @@ namespace garlic auto it = m_CreatedSessions.find (msgID); if (it != m_CreatedSessions.end ()) { - it->second->TagsConfirmed (msgID); + it->second->MessageConfirmed (msgID); m_CreatedSessions.erase (it); LogPrint (eLogInfo, "Garlic message ", msgID, " acknowledged"); } diff --git a/Garlic.h b/Garlic.h index 43214e75..4b02d987 100644 --- a/Garlic.h +++ b/Garlic.h @@ -39,6 +39,7 @@ namespace garlic const int INCOMING_TAGS_EXPIRATION_TIMEOUT = 960; // 16 minutes const int OUTGOING_TAGS_EXPIRATION_TIMEOUT = 720; // 12 minutes + const int LEASET_CONFIRMATION_TIMEOUT = 4000; // in milliseconds struct SessionTag: public i2p::data::Tag<32> { @@ -56,6 +57,13 @@ namespace garlic class GarlicDestination; class GarlicRoutingSession: public std::enable_shared_from_this { + enum LeaseSetUpdateStatus + { + eLeaseSetUpToDate = 0, + eLeaseSetUpdated, + eLeaseSetSubmitted + }; + struct UnconfirmedTags { UnconfirmedTags (int n): numTags (n), tagsCreationTime (0) { sessionTags = new SessionTag[numTags]; }; @@ -71,10 +79,10 @@ namespace garlic GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption ~GarlicRoutingSession (); I2NPMessage * WrapSingleMessage (I2NPMessage * msg); - void TagsConfirmed (uint32_t msgID); + void MessageConfirmed (uint32_t msgID); bool CleanupExpiredTags (); // returns true if something left - void SetLeaseSetUpdated () { m_LeaseSetUpdated = true; }; + void SetLeaseSetUpdated () { m_LeaseSetUpdateStatus = eLeaseSetUpdated; }; private: @@ -82,7 +90,8 @@ namespace garlic size_t CreateGarlicPayload (uint8_t * payload, const I2NPMessage * msg, UnconfirmedTags * newTags); size_t CreateGarlicClove (uint8_t * buf, const I2NPMessage * msg, bool isDestination); size_t CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID); - + + void TagsConfirmed (uint32_t msgID); UnconfirmedTags * GenerateSessionTags (); private: @@ -93,8 +102,11 @@ namespace garlic std::list m_SessionTags; int m_NumTags; std::map m_UnconfirmedTagsMsgs; - bool m_LeaseSetUpdated; - + + LeaseSetUpdateStatus m_LeaseSetUpdateStatus; + uint32_t m_LeaseSetUpdateMsgID; + uint64_t m_LeaseSetSubmissionTime; // in milliseconds + i2p::crypto::CBCEncryption m_Encryption; CryptoPP::AutoSeededRandomPool m_Rnd; };