diff --git a/Destination.cpp b/Destination.cpp index 26330c29..e6380ffd 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -140,7 +140,7 @@ namespace client m_IsRunning = true; m_Pool->SetLocalDestination (shared_from_this ()); m_Pool->SetActive (true); - m_Thread = new std::thread (std::bind (&ClientDestination::Run, this)); + m_Thread = new std::thread (std::bind (&ClientDestination::Run, shared_from_this ())); m_StreamingDestination = std::make_shared (shared_from_this ()); // TODO: m_StreamingDestination->Start (); for (auto it: m_StreamingDestinationsByPorts) @@ -148,7 +148,7 @@ namespace client m_CleanupTimer.expires_from_now (boost::posix_time::minutes (DESTINATION_CLEANUP_TIMEOUT)); m_CleanupTimer.async_wait (std::bind (&ClientDestination::HandleCleanupTimer, - this, std::placeholders::_1)); + shared_from_this (), std::placeholders::_1)); } } @@ -229,21 +229,22 @@ namespace client } data; memcpy (data.k, key, 32); memcpy (data.t, tag, 32); - m_Service.post ([this,data](void) + auto s = shared_from_this (); + m_Service.post ([s,data](void) { - this->AddSessionKey (data.k, data.t); + s->AddSessionKey (data.k, data.t); }); return true; } void ClientDestination::ProcessGarlicMessage (std::shared_ptr msg) { - m_Service.post (std::bind (&ClientDestination::HandleGarlicMessage, this, msg)); + m_Service.post (std::bind (&ClientDestination::HandleGarlicMessage, shared_from_this (), msg)); } void ClientDestination::ProcessDeliveryStatusMessage (std::shared_ptr msg) { - m_Service.post (std::bind (&ClientDestination::HandleDeliveryStatusMessage, this, msg)); + m_Service.post (std::bind (&ClientDestination::HandleDeliveryStatusMessage, shared_from_this (), msg)); } void ClientDestination::HandleI2NPMessage (const uint8_t * buf, size_t len, std::shared_ptr from) @@ -286,15 +287,20 @@ namespace client if (it != m_RemoteLeaseSets.end ()) { leaseSet = it->second; - leaseSet->Update (buf + offset, len - offset); - if (leaseSet->IsValid ()) - LogPrint (eLogDebug, "Remote LeaseSet updated"); - else - { - LogPrint (eLogDebug, "Remote LeaseSet update failed"); - m_RemoteLeaseSets.erase (it); - leaseSet = nullptr; + if (leaseSet->IsNewer (buf + offset, len - offset)) + { + leaseSet->Update (buf + offset, len - offset); + if (leaseSet->IsValid ()) + LogPrint (eLogDebug, "Remote LeaseSet updated"); + else + { + LogPrint (eLogDebug, "Remote LeaseSet update failed"); + m_RemoteLeaseSets.erase (it); + leaseSet = nullptr; + } } + else + LogPrint (eLogDebug, "Remote LeaseSet is older. Not updated"); } else { diff --git a/LeaseSet.cpp b/LeaseSet.cpp index 891b73d6..620c78db 100644 --- a/LeaseSet.cpp +++ b/LeaseSet.cpp @@ -182,7 +182,35 @@ namespace data m_IsValid = false; } } - + + uint64_t LeaseSet::ExtractTimestamp (const uint8_t * buf, size_t len) const + { + if (!m_Identity) return 0; + size_t size = m_Identity->GetFullLen (); + if (size > len) return 0; + size += 256; // encryption key + size += m_Identity->GetSigningPublicKeyLen (); // unused signing key + if (size > len) return 0; + uint8_t num = buf[size]; + size++; // num + if (size + num*44 > len) return 0; + uint64_t timestamp= 0 ; + for (int i = 0; i < num; i++) + { + size += 36; // gateway (32) + tunnelId(4) + auto endDate = bufbe64toh (buf + size); + size += 8; // end date + if (!timestamp || endDate < timestamp) + timestamp = endDate; + } + return timestamp; + } + + bool LeaseSet::IsNewer (const uint8_t * buf, size_t len) const + { + return true; //ExtractTimestamp (buf, len) > ExtractTimestamp (m_Buffer, m_BufferLen); + } + const std::vector > LeaseSet::GetNonExpiredLeases (bool withThreshold) const { auto ts = i2p::util::GetMillisecondsSinceEpoch (); diff --git a/LeaseSet.h b/LeaseSet.h index cffa60dd..0afca269 100644 --- a/LeaseSet.h +++ b/LeaseSet.h @@ -47,6 +47,7 @@ namespace data LeaseSet (std::shared_ptr pool); ~LeaseSet () { delete[] m_Buffer; }; void Update (const uint8_t * buf, size_t len); + bool IsNewer (const uint8_t * buf, size_t len) const; void PopulateLeases (); // from buffer std::shared_ptr GetIdentity () const { return m_Identity; }; @@ -69,6 +70,7 @@ namespace data private: void ReadFromBuffer (bool readIdentity = true); + uint64_t ExtractTimestamp (const uint8_t * buf, size_t len) const; // min expiration time private: