diff --git a/libi2pd_client/I2CP.cpp b/libi2pd_client/I2CP.cpp index 88465143..ccbdee4b 100644 --- a/libi2pd_client/I2CP.cpp +++ b/libi2pd_client/I2CP.cpp @@ -29,13 +29,15 @@ namespace client const std::map& params): LeaseSetDestination (service, isPublic, ¶ms), m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()), - m_IsCreatingLeaseSet (false), m_IsSameThread (isSameThread), m_LeaseSetCreationTimer (service) + m_IsCreatingLeaseSet (false), m_IsSameThread (isSameThread), + m_LeaseSetCreationTimer (service), m_ReadinessCheckTimer (service) { } void I2CPDestination::Stop () { m_LeaseSetCreationTimer.cancel (); + m_ReadinessCheckTimer.cancel (); LeaseSetDestination::Stop (); m_Owner = nullptr; } @@ -88,7 +90,7 @@ namespace client void I2CPDestination::CreateNewLeaseSet (const std::vector >& tunnels) { - boost::asio::post (GetService (), std::bind (&I2CPDestination::PostCreateNewLeaseSet, this, tunnels)); + boost::asio::post (GetService (), std::bind (&I2CPDestination::PostCreateNewLeaseSet, GetSharedFromThis (), tunnels)); } void I2CPDestination::PostCreateNewLeaseSet (std::vector > tunnels) @@ -98,6 +100,18 @@ namespace client LogPrint (eLogInfo, "I2CP: LeaseSet is being created"); return; } + m_ReadinessCheckTimer.cancel (); + if (!IsReady ()) + { + // try again later + m_ReadinessCheckTimer.expires_from_now (boost::posix_time::seconds(I2CP_DESTINATION_READINESS_CHECK_INTERVAL)); + m_ReadinessCheckTimer.async_wait( + [s=GetSharedFromThis (), tunnels=std::move(tunnels)](const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + s->PostCreateNewLeaseSet (tunnels); + }); + } uint8_t priv[256] = {0}; i2p::data::LocalLeaseSet ls (m_Identity, priv, tunnels); // we don't care about encryption key, we need leases only m_LeaseSetExpirationTime = ls.GetExpirationTime (); diff --git a/libi2pd_client/I2CP.h b/libi2pd_client/I2CP.h index d5ac648e..50b668d3 100644 --- a/libi2pd_client/I2CP.h +++ b/libi2pd_client/I2CP.h @@ -31,6 +31,7 @@ namespace client const size_t I2CP_MAX_MESSAGE_LENGTH = 65535; const size_t I2CP_MAX_SEND_QUEUE_SIZE = 1024*1024; // in bytes, 1M const int I2CP_LEASESET_CREATION_TIMEOUT = 10; // in seconds + const int I2CP_DESTINATION_READINESS_CHECK_INTERVAL = 5; // in seconds const int I2CP_SESSION_ACK_REQUEST_INTERVAL = 12100; // in milliseconds const size_t I2CP_HEADER_LENGTH_OFFSET = 0; @@ -131,7 +132,7 @@ namespace client uint8_t m_ECIESx25519PrivateKey[32]; uint64_t m_LeaseSetExpirationTime; bool m_IsCreatingLeaseSet, m_IsSameThread; - boost::asio::deadline_timer m_LeaseSetCreationTimer; + boost::asio::deadline_timer m_LeaseSetCreationTimer, m_ReadinessCheckTimer; i2p::util::MemoryPoolMt > m_I2NPMsgsPool; };