diff --git a/Destination.cpp b/Destination.cpp index 2df14a9f..d115f1fa 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -171,11 +171,29 @@ namespace client std::shared_ptr LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident) { + std::lock_guard lock(m_RemoteLeaseSetsMutex); auto it = m_RemoteLeaseSets.find (ident); if (it != m_RemoteLeaseSets.end ()) - { + { if (!it->second->IsExpired ()) + { + if (it->second->ExpiresSoon()) + { + LogPrint(eLogDebug, "Destination: Lease Set expires soon, updating before expire"); + // update now before expiration for smooth handover + RequestDestination(ident, [this, ident] (std::shared_ptr ls) { + if(ls && !ls->IsExpired()) + { + ls->PopulateLeases(); + { + std::lock_guard _lock(m_RemoteLeaseSetsMutex); + m_RemoteLeaseSets[ident] = ls; + } + } + }); + } return it->second; + } else LogPrint (eLogWarning, "Destination: remote LeaseSet expired"); } @@ -185,7 +203,10 @@ namespace client if (ls && !ls->IsExpired ()) { ls->PopulateLeases (); // since we don't store them in netdb - m_RemoteLeaseSets[ident] = ls; + { + std::lock_guard lock(m_RemoteLeaseSetsMutex); + m_RemoteLeaseSets[ident] = ls; + } return ls; } } @@ -279,6 +300,7 @@ namespace client if (buf[DATABASE_STORE_TYPE_OFFSET] == 1) // LeaseSet { LogPrint (eLogDebug, "Remote LeaseSet"); + std::lock_guard lock(m_RemoteLeaseSetsMutex); auto it = m_RemoteLeaseSets.find (buf + DATABASE_STORE_KEY_OFFSET); if (it != m_RemoteLeaseSets.end ()) { @@ -627,6 +649,7 @@ namespace client void LeaseSetDestination::CleanupRemoteLeaseSets () { auto ts = i2p::util::GetMillisecondsSinceEpoch (); + std::lock_guard lock(m_RemoteLeaseSetsMutex); for (auto it = m_RemoteLeaseSets.begin (); it != m_RemoteLeaseSets.end ();) { if (it->second->IsEmpty () || ts > it->second->GetExpirationTime ()) // leaseset expired diff --git a/Destination.h b/Destination.h index e64508c9..ad6318ef 100644 --- a/Destination.h +++ b/Destination.h @@ -122,6 +122,7 @@ namespace client std::thread * m_Thread; boost::asio::io_service m_Service; boost::asio::io_service::work m_Work; + mutable std::mutex m_RemoteLeaseSetsMutex; std::map > m_RemoteLeaseSets; std::map > m_LeaseSetRequests; diff --git a/LeaseSet.cpp b/LeaseSet.cpp index fafe14b7..a7fede01 100644 --- a/LeaseSet.cpp +++ b/LeaseSet.cpp @@ -162,7 +162,14 @@ namespace data { return ExtractTimestamp (buf, len) > ExtractTimestamp (m_Buffer, m_BufferLen); } - + + bool LeaseSet::ExpiresSoon(const uint64_t dlt) const + { + auto now = i2p::util::GetMillisecondsSinceEpoch (); + if (now >= m_ExpirationTime) return true; + return m_ExpirationTime - now <= dlt; + } + const std::vector > LeaseSet::GetNonExpiredLeases (bool withThreshold) const { auto ts = i2p::util::GetMillisecondsSinceEpoch (); diff --git a/LeaseSet.h b/LeaseSet.h index c174ac39..d9e74bab 100644 --- a/LeaseSet.h +++ b/LeaseSet.h @@ -60,6 +60,7 @@ namespace data bool IsExpired () const; bool IsEmpty () const { return m_Leases.empty (); }; uint64_t GetExpirationTime () const { return m_ExpirationTime; }; + bool ExpiresSoon(const uint64_t dlt=1000 * 5) const ; bool operator== (const LeaseSet& other) const { return m_BufferLen == other.m_BufferLen && !memcmp (m_Buffer, other.m_Buffer, m_BufferLen); }; diff --git a/NTCPSession.cpp b/NTCPSession.cpp index d2c03857..71cb21b3 100644 --- a/NTCPSession.cpp +++ b/NTCPSession.cpp @@ -768,6 +768,7 @@ namespace transport auto& addresses = context.GetRouterInfo ().GetAddresses (); for (auto address: addresses) { + if (!address) continue; if (address->transportStyle == i2p::data::RouterInfo::eTransportNTCP) { if (address->host.is_v4()) diff --git a/Transports.cpp b/Transports.cpp index a54455cc..f8af379f 100644 --- a/Transports.cpp +++ b/Transports.cpp @@ -114,6 +114,7 @@ namespace transport auto& addresses = context.GetRouterInfo ().GetAddresses (); for (auto address : addresses) { + if (!address) continue; if (m_NTCPServer == nullptr && enableNTCP) { m_NTCPServer = new NTCPServer ();