Browse Source

fixed race condition for publishing

pull/1313/head
orignal 6 years ago
parent
commit
8ec12a1b65
  1. 25
      libi2pd/Destination.cpp
  2. 5
      libi2pd/Destination.h
  3. 4
      libi2pd_client/I2CP.cpp

25
libi2pd/Destination.cpp

@ -272,15 +272,20 @@ namespace client
if (!m_Pool) return nullptr; if (!m_Pool) return nullptr;
if (!m_LeaseSet) if (!m_LeaseSet)
UpdateLeaseSet (); UpdateLeaseSet ();
return GetLeaseSetMt ();
}
std::shared_ptr<const i2p::data::LocalLeaseSet> LeaseSetDestination::GetLeaseSetMt ()
{
std::lock_guard<std::mutex> l(m_LeaseSetMutex); std::lock_guard<std::mutex> l(m_LeaseSetMutex);
return m_LeaseSet; return m_LeaseSet;
} }
void LeaseSetDestination::SetLeaseSet (i2p::data::LocalLeaseSet * newLeaseSet) void LeaseSetDestination::SetLeaseSet (std::shared_ptr<const i2p::data::LocalLeaseSet> newLeaseSet)
{ {
{ {
std::lock_guard<std::mutex> l(m_LeaseSetMutex); std::lock_guard<std::mutex> l(m_LeaseSetMutex);
m_LeaseSet.reset (newLeaseSet); m_LeaseSet = newLeaseSet;
} }
i2p::garlic::GarlicDestination::SetLeaseSetUpdated (); i2p::garlic::GarlicDestination::SetLeaseSetUpdated ();
if (m_IsPublic) if (m_IsPublic)
@ -505,7 +510,8 @@ namespace client
void LeaseSetDestination::Publish () void LeaseSetDestination::Publish ()
{ {
if (!m_LeaseSet || !m_Pool) auto leaseSet = GetLeaseSetMt ();
if (!leaseSet || !m_Pool)
{ {
LogPrint (eLogError, "Destination: Can't publish non-existing LeaseSet"); LogPrint (eLogError, "Destination: Can't publish non-existing LeaseSet");
return; return;
@ -537,7 +543,7 @@ namespace client
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels"); LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
return; return;
} }
auto floodfill = i2p::data::netdb.GetClosestFloodfill (m_LeaseSet->GetIdentHash (), m_ExcludedFloodfills); auto floodfill = i2p::data::netdb.GetClosestFloodfill (leaseSet->GetIdentHash (), m_ExcludedFloodfills);
if (!floodfill) if (!floodfill)
{ {
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found"); LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
@ -547,7 +553,7 @@ namespace client
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4);
auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (m_LeaseSet, m_PublishReplyToken, inbound)); auto msg = WrapMessage (floodfill, i2p::CreateDatabaseStoreMsg (leaseSet, m_PublishReplyToken, inbound));
m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT)); m_PublishConfirmationTimer.expires_from_now (boost::posix_time::seconds(PUBLISH_CONFIRMATION_TIMEOUT));
m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer, m_PublishConfirmationTimer.async_wait (std::bind (&LeaseSetDestination::HandlePublishConfirmationTimer,
shared_from_this (), std::placeholders::_1)); shared_from_this (), std::placeholders::_1));
@ -592,7 +598,8 @@ namespace client
{ {
if (leaseSet) if (leaseSet)
{ {
if (s->m_LeaseSet && *s->m_LeaseSet == *leaseSet) auto ls = s->GetLeaseSetMt ();
if (ls && *ls == *leaseSet)
{ {
// we got latest LeasetSet // we got latest LeasetSet
LogPrint (eLogDebug, "Destination: published LeaseSet verified for ", GetIdentHash().ToBase32()); LogPrint (eLogDebug, "Destination: published LeaseSet verified for ", GetIdentHash().ToBase32());
@ -1081,10 +1088,10 @@ namespace client
void ClientDestination::CreateNewLeaseSet (std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels) void ClientDestination::CreateNewLeaseSet (std::vector<std::shared_ptr<i2p::tunnel::InboundTunnel> > tunnels)
{ {
i2p::data::LocalLeaseSet * leaseSet = nullptr; std::shared_ptr<i2p::data::LocalLeaseSet> leaseSet;
if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET) if (GetLeaseSetType () == i2p::data::NETDB_STORE_TYPE_LEASESET)
{ {
leaseSet = new i2p::data::LocalLeaseSet (GetIdentity (), m_EncryptionPublicKey, tunnels); leaseSet = std::make_shared<i2p::data::LocalLeaseSet> (GetIdentity (), m_EncryptionPublicKey, tunnels);
// sign // sign
Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ()); Sign (leaseSet->GetBuffer (), leaseSet->GetBufferLen () - leaseSet->GetSignatureLen (), leaseSet->GetSignature ());
} }
@ -1092,7 +1099,7 @@ namespace client
{ {
// standard LS2 (type 3) assumed for now. TODO: implement others // standard LS2 (type 3) assumed for now. TODO: implement others
auto keyLen = m_Decryptor ? m_Decryptor->GetPublicKeyLen () : 256; auto keyLen = m_Decryptor ? m_Decryptor->GetPublicKeyLen () : 256;
leaseSet = new i2p::data::LocalLeaseSet2 (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2, leaseSet = std::make_shared<i2p::data::LocalLeaseSet2> (i2p::data::NETDB_STORE_TYPE_STANDARD_LEASESET2,
m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels); m_Keys, m_EncryptionKeyType, keyLen, m_EncryptionPublicKey, tunnels);
} }
SetLeaseSet (leaseSet); SetLeaseSet (leaseSet);

5
libi2pd/Destination.h

@ -127,7 +127,7 @@ namespace client
protected: protected:
void SetLeaseSet (i2p::data::LocalLeaseSet * newLeaseSet); void SetLeaseSet (std::shared_ptr<const i2p::data::LocalLeaseSet> newLeaseSet);
int GetLeaseSetType () const { return m_LeaseSetType; }; int GetLeaseSetType () const { return m_LeaseSetType; };
void SetLeaseSetType (int leaseSetType) { m_LeaseSetType = leaseSetType; }; void SetLeaseSetType (int leaseSetType) { m_LeaseSetType = leaseSetType; };
virtual void CleanupDestination () {}; // additional clean up in derived classes virtual void CleanupDestination () {}; // additional clean up in derived classes
@ -139,6 +139,7 @@ namespace client
void Run (); void Run ();
void UpdateLeaseSet (); void UpdateLeaseSet ();
std::shared_ptr<const i2p::data::LocalLeaseSet> GetLeaseSetMt ();
void Publish (); void Publish ();
void HandlePublishConfirmationTimer (const boost::system::error_code& ecode); void HandlePublishConfirmationTimer (const boost::system::error_code& ecode);
void HandlePublishVerificationTimer (const boost::system::error_code& ecode); void HandlePublishVerificationTimer (const boost::system::error_code& ecode);
@ -164,7 +165,7 @@ namespace client
std::shared_ptr<i2p::tunnel::TunnelPool> m_Pool; std::shared_ptr<i2p::tunnel::TunnelPool> m_Pool;
std::mutex m_LeaseSetMutex; std::mutex m_LeaseSetMutex;
std::shared_ptr<i2p::data::LocalLeaseSet> m_LeaseSet; std::shared_ptr<const i2p::data::LocalLeaseSet> m_LeaseSet;
bool m_IsPublic; bool m_IsPublic;
uint32_t m_PublishReplyToken; uint32_t m_PublishReplyToken;
uint64_t m_LastSubmissionTime; // in seconds uint64_t m_LastSubmissionTime; // in seconds

4
libi2pd_client/I2CP.cpp

@ -63,14 +63,14 @@ namespace client
void I2CPDestination::LeaseSetCreated (const uint8_t * buf, size_t len) void I2CPDestination::LeaseSetCreated (const uint8_t * buf, size_t len)
{ {
auto ls = new i2p::data::LocalLeaseSet (m_Identity, buf, len); auto ls = std::make_shared<i2p::data::LocalLeaseSet> (m_Identity, buf, len);
ls->SetExpirationTime (m_LeaseSetExpirationTime); ls->SetExpirationTime (m_LeaseSetExpirationTime);
SetLeaseSet (ls); SetLeaseSet (ls);
} }
void I2CPDestination::LeaseSet2Created (uint8_t storeType, const uint8_t * buf, size_t len) void I2CPDestination::LeaseSet2Created (uint8_t storeType, const uint8_t * buf, size_t len)
{ {
auto ls = new i2p::data::LocalLeaseSet2 (storeType, m_Identity, buf, len); auto ls = std::make_shared<i2p::data::LocalLeaseSet2> (storeType, m_Identity, buf, len);
ls->SetExpirationTime (m_LeaseSetExpirationTime); ls->SetExpirationTime (m_LeaseSetExpirationTime);
SetLeaseSet (ls); SetLeaseSet (ls);
} }

Loading…
Cancel
Save