From a1322d4667753fef7693d35fc5ee32b7847ac907 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 1 Jun 2024 17:46:18 -0400 Subject: [PATCH] move unsent I2NP messages to new session if replaced --- libi2pd/SSU2.cpp | 4 +++- libi2pd/SSU2Session.cpp | 18 +++++++++++++++++- libi2pd/SSU2Session.h | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/libi2pd/SSU2.cpp b/libi2pd/SSU2.cpp index 15d54395..0a5574d5 100644 --- a/libi2pd/SSU2.cpp +++ b/libi2pd/SSU2.cpp @@ -455,10 +455,12 @@ namespace transport if (ident) { auto ret = m_SessionsByRouterHash.emplace (ident->GetIdentHash (), session); - if (!ret.second) + if (!ret.second && ret.first->second != session) { // session already exists LogPrint (eLogWarning, "SSU2: Session to ", ident->GetIdentHash ().ToBase64 (), " already exists"); + // move unsent msgs to new session + ret.first->second->MoveSendQueue (session); // terminate existing GetService ().post (std::bind (&SSU2Session::RequestTermination, ret.first->second, eSSU2TerminationReasonReplacedByNewSession)); // update session diff --git a/libi2pd/SSU2Session.cpp b/libi2pd/SSU2Session.cpp index ff23f0d7..9552d20a 100644 --- a/libi2pd/SSU2Session.cpp +++ b/libi2pd/SSU2Session.cpp @@ -313,6 +313,7 @@ namespace transport m_SentHandshakePacket.reset (nullptr); m_ConnectTimer.cancel (); SetTerminationTimeout (SSU2_TERMINATION_TIMEOUT); + SendQueue (); transports.PeerConnected (shared_from_this ()); if (m_OnEstablished) { @@ -389,9 +390,24 @@ namespace transport SetSendQueueSize (m_SendQueue.size ()); } + void SSU2Session::MoveSendQueue (std::shared_ptr other) + { + if (!other || m_SendQueue.empty ()) return; + std::vector > msgs; + auto ts = i2p::util::GetMillisecondsSinceEpoch (); + for (auto it: m_SendQueue) + if (!it->IsExpired (ts)) + msgs.push_back (it); + else + it->Drop (); + m_SendQueue.clear (); + if (!msgs.empty ()) + other->PostI2NPMessages (msgs); + } + bool SSU2Session::SendQueue () { - if (!m_SendQueue.empty () && m_SentPackets.size () <= m_WindowSize) + if (!m_SendQueue.empty () && m_SentPackets.size () <= m_WindowSize && IsEstablished ()) { auto ts = i2p::util::GetMillisecondsSinceEpoch (); uint64_t mts = i2p::util::GetMonotonicMicroseconds (); diff --git a/libi2pd/SSU2Session.h b/libi2pd/SSU2Session.h index e4744b02..76dc55df 100644 --- a/libi2pd/SSU2Session.h +++ b/libi2pd/SSU2Session.h @@ -255,6 +255,7 @@ namespace transport void Done () override; void SendLocalRouterInfo (bool update) override; void SendI2NPMessages (const std::vector >& msgs) override; + void MoveSendQueue (std::shared_ptr other); uint32_t GetRelayTag () const override { return m_RelayTag; }; size_t Resend (uint64_t ts); // return number of resent packets uint64_t GetLastResendTime () const { return m_LastResendTime; };