From 8f562215b052bedb92d4d38854163d4e87263b66 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 26 Jan 2015 11:56:10 -0500 Subject: [PATCH] separate inbound and outbound pending tunnels --- I2NPProtocol.cpp | 8 ++++---- Tunnel.cpp | 53 ++++++++++++++++++++++++++++++++++++++---------- Tunnel.h | 15 +++++++++++--- 3 files changed, 58 insertions(+), 18 deletions(-) diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index b560daa3..638122b5 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -312,7 +312,7 @@ namespace i2p int num = buf[0]; LogPrint ("VariableTunnelBuild ", num, " records"); - i2p::tunnel::Tunnel * tunnel = i2p::tunnel::tunnels.GetPendingTunnel (replyMsgID); + auto tunnel = i2p::tunnel::tunnels.GetPendingInboundTunnel (replyMsgID); if (tunnel) { // endpoint of inbound tunnel @@ -321,7 +321,7 @@ namespace i2p { LogPrint ("Inbound tunnel ", tunnel->GetTunnelID (), " has been created"); tunnel->SetState (i2p::tunnel::eTunnelStateEstablished); - i2p::tunnel::tunnels.AddInboundTunnel (static_cast(tunnel)); + i2p::tunnel::tunnels.AddInboundTunnel (tunnel); } else { @@ -373,7 +373,7 @@ namespace i2p void HandleVariableTunnelBuildReplyMsg (uint32_t replyMsgID, uint8_t * buf, size_t len) { LogPrint ("VariableTunnelBuildReplyMsg replyMsgID=", replyMsgID); - i2p::tunnel::Tunnel * tunnel = i2p::tunnel::tunnels.GetPendingTunnel (replyMsgID); + auto tunnel = i2p::tunnel::tunnels.GetPendingOutboundTunnel (replyMsgID); if (tunnel) { // reply for outbound tunnel @@ -381,7 +381,7 @@ namespace i2p { LogPrint ("Outbound tunnel ", tunnel->GetTunnelID (), " has been created"); tunnel->SetState (i2p::tunnel::eTunnelStateEstablished); - i2p::tunnel::tunnels.AddOutboundTunnel (static_cast(tunnel)); + i2p::tunnel::tunnels.AddOutboundTunnel (tunnel); } else { diff --git a/Tunnel.cpp b/Tunnel.cpp index efa0e8db..3027bcad 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -222,10 +222,13 @@ namespace tunnel m_TransitTunnels.clear (); ManagePendingTunnels (); - for (auto& it : m_PendingTunnels) + for (auto& it : m_PendingInboundTunnels) delete it.second; - m_PendingTunnels.clear (); + m_PendingInboundTunnels.clear (); + for (auto& it : m_PendingOutboundTunnels) + delete it.second; + m_PendingOutboundTunnels.clear (); } InboundTunnel * Tunnels::GetInboundTunnel (uint32_t tunnelID) @@ -243,11 +246,22 @@ namespace tunnel return it->second; return nullptr; } - - Tunnel * Tunnels::GetPendingTunnel (uint32_t replyMsgID) + + InboundTunnel * Tunnels::GetPendingInboundTunnel (uint32_t replyMsgID) { - auto it = m_PendingTunnels.find(replyMsgID); - if (it != m_PendingTunnels.end () && it->second->GetState () == eTunnelStatePending) + return GetPendingTunnel (replyMsgID, m_PendingInboundTunnels); + } + + OutboundTunnel * Tunnels::GetPendingOutboundTunnel (uint32_t replyMsgID) + { + return GetPendingTunnel (replyMsgID, m_PendingOutboundTunnels); + } + + template + TTunnel * Tunnels::GetPendingTunnel (uint32_t replyMsgID, const std::map& pendingTunnels) + { + auto it = pendingTunnels.find(replyMsgID); + if (it != pendingTunnels.end () && it->second->GetState () == eTunnelStatePending) { it->second->SetState (eTunnelStateBuildReplyReceived); return it->second; @@ -447,10 +461,17 @@ namespace tunnel } void Tunnels::ManagePendingTunnels () + { + ManagePendingTunnels (m_PendingInboundTunnels); + ManagePendingTunnels (m_PendingOutboundTunnels); + } + + template + void Tunnels::ManagePendingTunnels (PendingTunnels& pendingTunnels) { // check pending tunnel. delete failed or timeout uint64_t ts = i2p::util::GetSecondsSinceEpoch (); - for (auto it = m_PendingTunnels.begin (); it != m_PendingTunnels.end ();) + for (auto it = pendingTunnels.begin (); it != pendingTunnels.end ();) { auto tunnel = it->second; switch (tunnel->GetState ()) @@ -460,7 +481,7 @@ namespace tunnel { LogPrint ("Pending tunnel build request ", it->first, " timeout. Deleted"); delete tunnel; - it = m_PendingTunnels.erase (it); + it = pendingTunnels.erase (it); } else it++; @@ -468,14 +489,14 @@ namespace tunnel case eTunnelStateBuildFailed: LogPrint ("Pending tunnel build request ", it->first, " failed. Deleted"); delete tunnel; - it = m_PendingTunnels.erase (it); + it = pendingTunnels.erase (it); break; case eTunnelStateBuildReplyReceived: // intermidiate state, will be either established of build failed it++; break; default: - it = m_PendingTunnels.erase (it); + it = pendingTunnels.erase (it); } } } @@ -625,11 +646,21 @@ namespace tunnel { TTunnel * newTunnel = new TTunnel (config); uint32_t replyMsgID = i2p::context.GetRandomNumberGenerator ().GenerateWord32 (); - m_PendingTunnels[replyMsgID] = newTunnel; + AddPendingTunnel (replyMsgID, newTunnel); newTunnel->Build (replyMsgID, outboundTunnel); return newTunnel; } + void Tunnels::AddPendingTunnel (uint32_t replyMsgID, InboundTunnel * tunnel) + { + m_PendingInboundTunnels[replyMsgID] = tunnel; + } + + void Tunnels::AddPendingTunnel (uint32_t replyMsgID, OutboundTunnel * tunnel) + { + m_PendingOutboundTunnels[replyMsgID] = tunnel; + } + void Tunnels::AddOutboundTunnel (OutboundTunnel * newTunnel) { std::unique_lock l(m_OutboundTunnelsMutex); diff --git a/Tunnel.h b/Tunnel.h index 6f7cf709..2cd9c0fb 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -121,7 +121,8 @@ namespace tunnel void Stop (); InboundTunnel * GetInboundTunnel (uint32_t tunnelID); - Tunnel * GetPendingTunnel (uint32_t replyMsgID); + InboundTunnel * GetPendingInboundTunnel (uint32_t replyMsgID); + OutboundTunnel * GetPendingOutboundTunnel (uint32_t replyMsgID); InboundTunnel * GetNextInboundTunnel (); OutboundTunnel * GetNextOutboundTunnel (); std::shared_ptr GetExploratoryPool () const { return m_ExploratoryPool; }; @@ -134,12 +135,17 @@ namespace tunnel void PostTunnelData (const std::vector& msgs); template TTunnel * CreateTunnel (TunnelConfig * config, OutboundTunnel * outboundTunnel = 0); + void AddPendingTunnel (uint32_t replyMsgID, InboundTunnel * tunnel); + void AddPendingTunnel (uint32_t replyMsgID, OutboundTunnel * tunnel); std::shared_ptr CreateTunnelPool (i2p::garlic::GarlicDestination * localDestination, int numInboundHops, int numOuboundHops); void DeleteTunnelPool (std::shared_ptr pool); void StopTunnelPool (std::shared_ptr pool); private: - + + template + TTunnel * GetPendingTunnel (uint32_t replyMsgID, const std::map& pendingTunnels); + void HandleTunnelGatewayMsg (TunnelBase * tunnel, I2NPMessage * msg); void Run (); @@ -148,6 +154,8 @@ namespace tunnel void ManageInboundTunnels (); void ManageTransitTunnels (); void ManagePendingTunnels (); + template + void ManagePendingTunnels (PendingTunnels& pendingTunnels); void ManageTunnelPools (); void CreateZeroHopsInboundTunnel (); @@ -156,7 +164,8 @@ namespace tunnel bool m_IsRunning; std::thread * m_Thread; - std::map m_PendingTunnels; // by replyMsgID + std::map m_PendingInboundTunnels; // by replyMsgID + std::map m_PendingOutboundTunnels; // by replyMsgID std::mutex m_InboundTunnelsMutex; std::map m_InboundTunnels; std::mutex m_OutboundTunnelsMutex;