diff --git a/Destination.cpp b/Destination.cpp index aee69c2b..751d885f 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -226,9 +226,8 @@ namespace stream void StreamingDestination::SetLeaseSetUpdated () { + i2p::garlic::GarlicDestination::SetLeaseSetUpdated (); UpdateLeaseSet (); - for (auto it: m_Streams) - it.second->SetLeaseSetUpdated (); if (m_IsPublic) i2p::data::netdb.PublishLeaseSet (m_LeaseSet, m_Pool); } diff --git a/Garlic.cpp b/Garlic.cpp index b89bf84a..9b9c0a23 100644 --- a/Garlic.cpp +++ b/Garlic.cpp @@ -17,7 +17,8 @@ namespace garlic GarlicRoutingSession::GarlicRoutingSession (GarlicDestination * owner, const i2p::data::RoutingDestination * destination, int numTags): m_Owner (owner), m_Destination (destination), m_IsAcknowledged (false), - m_NumTags (numTags), m_NextTag (-1), m_SessionTags (0), m_TagsCreationTime (0) + m_NumTags (numTags), m_NextTag (-1), m_SessionTags (0), m_TagsCreationTime (0), + m_LeaseSetUpdated (numTags > 0) { // create new session tags and session key m_Rnd.GenerateBlock (m_SessionKey, 32); @@ -33,7 +34,7 @@ namespace garlic GarlicRoutingSession::GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag): m_Owner (nullptr), m_Destination (nullptr), m_IsAcknowledged (true), m_NumTags (1), - m_NextTag (0) + m_NextTag (0), m_LeaseSetUpdated (false) { memcpy (m_SessionKey, sessionKey, 32); m_Encryption.SetKey (m_SessionKey); @@ -58,7 +59,7 @@ namespace garlic } } - I2NPMessage * GarlicRoutingSession::WrapSingleMessage (I2NPMessage * msg, bool attachLeaseSet) + I2NPMessage * GarlicRoutingSession::WrapSingleMessage (I2NPMessage * msg) { I2NPMessage * m = NewI2NPMessage (); size_t len = 0; @@ -117,7 +118,7 @@ namespace garlic } } // AES block - len += CreateAESBlock (buf, msg, attachLeaseSet); + len += CreateAESBlock (buf, msg); m_NextTag++; *(uint32_t *)(m->GetPayload ()) = htobe32 (len); m->len += len + 4; @@ -127,7 +128,7 @@ namespace garlic return m; } - size_t GarlicRoutingSession::CreateAESBlock (uint8_t * buf, const I2NPMessage * msg, bool attachLeaseSet) + size_t GarlicRoutingSession::CreateAESBlock (uint8_t * buf, const I2NPMessage * msg) { size_t blockSize = 0; *(uint16_t *)buf = m_NextTag < 0 ? htobe16 (m_NumTags) : 0; // tag count @@ -146,7 +147,7 @@ namespace garlic blockSize += 32; buf[blockSize] = 0; // flag blockSize++; - size_t len = CreateGarlicPayload (buf + blockSize, msg, attachLeaseSet); + size_t len = CreateGarlicPayload (buf + blockSize, msg); *payloadSize = htobe32 (len); CryptoPP::SHA256().CalculateDigest(payloadHash, buf + blockSize, len); blockSize += len; @@ -157,7 +158,7 @@ namespace garlic return blockSize; } - size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, const I2NPMessage * msg, bool attachLeaseSet) + size_t GarlicRoutingSession::CreateGarlicPayload (uint8_t * payload, const I2NPMessage * msg) { uint64_t ts = i2p::util::GetMillisecondsSinceEpoch () + 5000; // 5 sec uint32_t msgID = m_Rnd.GenerateWord32 (); @@ -180,8 +181,9 @@ namespace garlic else LogPrint ("DeliveryStatus clove was not created"); } - if (attachLeaseSet) + if (m_LeaseSetUpdated) { + m_LeaseSetUpdated = false; // clove if our leaseSet must be attached auto leaseSet = CreateDatabaseStoreMsg (m_Owner->GetLeaseSet ()); size += CreateGarlicClove (payload + size, leaseSet, false); @@ -428,10 +430,10 @@ namespace garlic } I2NPMessage * GarlicDestination::WrapMessage (const i2p::data::RoutingDestination& destination, - I2NPMessage * msg, const i2p::data::LeaseSet * leaseSet) + I2NPMessage * msg, bool attachLeaseSet) { - auto session = GetRoutingSession (destination, leaseSet ? 32 : 0); // don't use tag if no LeaseSet - return session->WrapSingleMessage (msg, leaseSet); + auto session = GetRoutingSession (destination, attachLeaseSet ? 32 : 0); // don't use tag if no LeaseSet + return session->WrapSingleMessage (msg); } GarlicRoutingSession * GarlicDestination::GetRoutingSession ( @@ -472,5 +474,12 @@ namespace garlic } DeleteI2NPMessage (msg); } + + void GarlicDestination::SetLeaseSetUpdated () + { + std::unique_lock l(m_CreatedSessionsMutex); + for (auto it: m_Sessions) + it.second->SetLeaseSetUpdated (); + } } } diff --git a/Garlic.h b/Garlic.h index 2767b2f2..33739d8a 100644 --- a/Garlic.h +++ b/Garlic.h @@ -48,16 +48,18 @@ namespace garlic GarlicRoutingSession (GarlicDestination * owner, const i2p::data::RoutingDestination * destination, int numTags); GarlicRoutingSession (const uint8_t * sessionKey, const SessionTag& sessionTag); // one time encryption ~GarlicRoutingSession (); - I2NPMessage * WrapSingleMessage (I2NPMessage * msg, bool attachLeaseSet = false); + I2NPMessage * WrapSingleMessage (I2NPMessage * msg); int GetNextTag () const { return m_NextTag; }; - + bool IsAcknowledged () const { return m_IsAcknowledged; }; void SetAcknowledged (bool acknowledged) { m_IsAcknowledged = acknowledged; }; + + void SetLeaseSetUpdated () { m_LeaseSetUpdated = true; }; private: - size_t CreateAESBlock (uint8_t * buf, const I2NPMessage * msg, bool attachLeaseSet); - size_t CreateGarlicPayload (uint8_t * payload, const I2NPMessage * msg, bool attachLeaseSet); + size_t CreateAESBlock (uint8_t * buf, const I2NPMessage * msg); + size_t CreateGarlicPayload (uint8_t * payload, const I2NPMessage * msg); size_t CreateGarlicClove (uint8_t * buf, const I2NPMessage * msg, bool isDestination); size_t CreateDeliveryStatusClove (uint8_t * buf, uint32_t msgID); @@ -72,6 +74,7 @@ namespace garlic int m_NumTags, m_NextTag; SessionTag * m_SessionTags; // m_NumTags*32 bytes uint32_t m_TagsCreationTime; // seconds since epoch + bool m_LeaseSetUpdated; i2p::crypto::CBCEncryption m_Encryption; CryptoPP::AutoSeededRandomPool m_Rnd; @@ -86,7 +89,7 @@ namespace garlic GarlicRoutingSession * GetRoutingSession (const i2p::data::RoutingDestination& destination, int numTags); I2NPMessage * WrapMessage (const i2p::data::RoutingDestination& destination, - I2NPMessage * msg, const i2p::data::LeaseSet * leaseSet = nullptr); + I2NPMessage * msg, bool attachLeaseSet = false); void AddSessionKey (const uint8_t * key, const uint8_t * tag); // one tag void HandleGarlicMessage (I2NPMessage * msg); @@ -94,6 +97,7 @@ namespace garlic void DeliveryStatusSent (GarlicRoutingSession * session, uint32_t msgID); void HandleDeliveryStatusMessage (I2NPMessage * msg); + virtual void SetLeaseSetUpdated (); virtual const i2p::data::LeaseSet * GetLeaseSet () = 0; // TODO private: diff --git a/Identity.h b/Identity.h index 291edbec..95cc6d63 100644 --- a/Identity.h +++ b/Identity.h @@ -242,7 +242,6 @@ namespace data virtual const PrivateKeys& GetPrivateKeys () const = 0; virtual const uint8_t * GetEncryptionPrivateKey () const = 0; virtual const uint8_t * GetEncryptionPublicKey () const = 0; - virtual void SetLeaseSetUpdated () = 0; virtual void HandleDataMessage (const uint8_t * buf, size_t len) = 0; const IdentityEx& GetIdentity () const { return GetPrivateKeys ().GetPublic (); }; diff --git a/NetDb.cpp b/NetDb.cpp index 62291db7..44624ef0 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -669,7 +669,7 @@ namespace data { uint8_t * sessionTag = sessionKey + 33; // take first tag i2p::garlic::GarlicRoutingSession garlic (sessionKey, sessionTag); - replyMsg = garlic.WrapSingleMessage (replyMsg, nullptr); + replyMsg = garlic.WrapSingleMessage (replyMsg); } } auto exploratoryPool = i2p::tunnel::tunnels.GetExploratoryPool (); diff --git a/Streaming.cpp b/Streaming.cpp index ee53d41f..24812b31 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -13,7 +13,7 @@ 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_LocalDestination (local), m_RemoteLeaseSet (&remote), m_RoutingSession (nullptr), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service) { m_RecvStreamID = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (); @@ -22,8 +22,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_RoutingSession (nullptr), + m_IsOpen (false), m_LocalDestination (local), m_RemoteLeaseSet (nullptr), m_RoutingSession (nullptr), m_ReceiveTimer (m_Service), m_ResendTimer (m_Service) { m_RecvStreamID = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (); @@ -419,15 +418,13 @@ namespace stream for (auto it: packets) { auto msg = m_RoutingSession->WrapSingleMessage ( - m_LocalDestination.CreateDataMessage (it->GetBuffer (), it->GetLength ()), - m_LeaseSetUpdated); + m_LocalDestination.CreateDataMessage (it->GetBuffer (), it->GetLength ())); msgs.push_back (i2p::tunnel::TunnelMessageBlock { i2p::tunnel::eDeliveryTypeTunnel, m_CurrentRemoteLease.tunnelGateway, m_CurrentRemoteLease.tunnelID, msg }); - m_LeaseSetUpdated = false; // send leaseSet only one time } m_LocalDestination.SendTunnelDataMsgs (msgs); } diff --git a/Streaming.h b/Streaming.h index fbb39659..f2ea5533 100644 --- a/Streaming.h +++ b/Streaming.h @@ -96,8 +96,6 @@ namespace stream void AsyncReceive (const Buffer& buffer, ReceiveHandler handler, int timeout = 0); void Close (); - - void SetLeaseSetUpdated () { m_LeaseSetUpdated = true; }; private: @@ -123,7 +121,7 @@ namespace stream boost::asio::io_service& m_Service; uint32_t m_SendStreamID, m_RecvStreamID, m_SequenceNumber; int32_t m_LastReceivedSequenceNumber; - bool m_IsOpen, m_LeaseSetUpdated; + bool m_IsOpen; StreamingDestination& m_LocalDestination; i2p::data::IdentityEx m_RemoteIdentity; const i2p::data::LeaseSet * m_RemoteLeaseSet;