From b8d74dab477e712b4c64c376f08147414d7b3d69 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 2 Feb 2025 16:49:37 -0500 Subject: [PATCH] recreate tunnels in random order --- libi2pd/Tunnel.cpp | 59 ++++++++++++++++++++++++++++++++++++---------- libi2pd/Tunnel.h | 7 ++++-- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index 0d3f67db..f8be27ec 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -281,6 +281,21 @@ namespace tunnel m_Endpoint.HandleDecryptedTunnelDataMsg (msg); } + bool InboundTunnel::Recreate () + { + if (!IsRecreated ()) + { + auto pool = GetTunnelPool (); + if (pool) + { + SetRecreated (true); + pool->RecreateInboundTunnel (std::static_pointer_cast(shared_from_this ())); + return true; + } + } + return false; + } + ZeroHopsInboundTunnel::ZeroHopsInboundTunnel (): InboundTunnel (std::make_shared ()), m_NumReceivedBytes (0) @@ -331,6 +346,21 @@ namespace tunnel LogPrint (eLogError, "Tunnel: Incoming message for outbound tunnel ", GetTunnelID ()); } + bool OutboundTunnel::Recreate () + { + if (!IsRecreated ()) + { + auto pool = GetTunnelPool (); + if (pool) + { + SetRecreated (true); + pool->RecreateOutboundTunnel (std::static_pointer_cast(shared_from_this ())); + return true; + } + } + return false; + } + ZeroHopsOutboundTunnel::ZeroHopsOutboundTunnel (): OutboundTunnel (std::make_shared ()), m_NumSentBytes (0) @@ -437,7 +467,7 @@ namespace tunnel std::shared_ptr Tunnels::GetNextOutboundTunnel () { if (m_OutboundTunnels.empty ()) return nullptr; - uint32_t ind = rand () % m_OutboundTunnels.size (), i = 0; + uint32_t ind = m_Rng () % m_OutboundTunnels.size (), i = 0; std::shared_ptr tunnel; for (const auto& it: m_OutboundTunnels) { @@ -714,8 +744,17 @@ namespace tunnel void Tunnels::ManageTunnels (uint64_t ts) { ManagePendingTunnels (ts); - ManageInboundTunnels (ts); - ManageOutboundTunnels (ts); + std::vector > tunnelsToRecreate; + ManageInboundTunnels (ts, tunnelsToRecreate); + ManageOutboundTunnels (ts, tunnelsToRecreate); + // rec-create in random order + if (!tunnelsToRecreate.empty ()) + { + if (tunnelsToRecreate.size () > 1) + std::shuffle (tunnelsToRecreate.begin(), tunnelsToRecreate.end(), m_Rng); + for (auto& it: tunnelsToRecreate) + it->Recreate (); + } } void Tunnels::ManagePendingTunnels (uint64_t ts) @@ -778,7 +817,7 @@ namespace tunnel } } - void Tunnels::ManageOutboundTunnels (uint64_t ts) + void Tunnels::ManageOutboundTunnels (uint64_t ts, std::vector >& toRecreate) { for (auto it = m_OutboundTunnels.begin (); it != m_OutboundTunnels.end ();) { @@ -802,10 +841,7 @@ namespace tunnel auto pool = tunnel->GetTunnelPool (); // let it die if the tunnel pool has been reconfigured and this is old if (pool && tunnel->GetNumHops() == pool->GetNumOutboundHops()) - { - tunnel->SetRecreated (true); - pool->RecreateOutboundTunnel (tunnel); - } + toRecreate.push_back (tunnel); } if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) tunnel->SetState (eTunnelStateExpiring); @@ -830,7 +866,7 @@ namespace tunnel } } - void Tunnels::ManageInboundTunnels (uint64_t ts) + void Tunnels::ManageInboundTunnels (uint64_t ts, std::vector >& toRecreate) { for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();) { @@ -854,10 +890,7 @@ namespace tunnel auto pool = tunnel->GetTunnelPool (); // let it die if the tunnel pool was reconfigured and has different number of hops if (pool && tunnel->GetNumHops() == pool->GetNumInboundHops()) - { - tunnel->SetRecreated (true); - pool->RecreateInboundTunnel (tunnel); - } + toRecreate.push_back (tunnel); } if (ts + TUNNEL_EXPIRATION_THRESHOLD > tunnel->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 0cb87ace..5d21cd8b 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -99,6 +99,7 @@ namespace tunnel void SetRecreated (bool recreated) { m_IsRecreated = recreated; }; int GetNumHops () const { return m_Hops.size (); }; virtual bool IsInbound() const = 0; + virtual bool Recreate () = 0; std::shared_ptr GetTunnelPool () const { return m_Pool; }; void SetTunnelPool (std::shared_ptr pool) { m_Pool = pool; }; @@ -150,6 +151,7 @@ namespace tunnel void HandleTunnelDataMsg (std::shared_ptr&& tunnelMsg) override; bool IsInbound() const override { return false; } + bool Recreate () override; private: @@ -166,6 +168,7 @@ namespace tunnel void HandleTunnelDataMsg (std::shared_ptr&& msg) override; virtual size_t GetNumReceivedBytes () const { return m_Endpoint.GetNumReceivedBytes (); }; bool IsInbound() const override { return true; } + bool Recreate () override; // override TunnelBase void Cleanup () override { m_Endpoint.Cleanup (); }; @@ -262,8 +265,8 @@ namespace tunnel void Run (); void ManageTunnels (uint64_t ts); - void ManageOutboundTunnels (uint64_t ts); - void ManageInboundTunnels (uint64_t ts); + void ManageOutboundTunnels (uint64_t ts, std::vector >& toRecreate); + void ManageInboundTunnels (uint64_t ts, std::vector >& toRecreate); void ManagePendingTunnels (uint64_t ts); template void ManagePendingTunnels (PendingTunnels& pendingTunnels, uint64_t ts);