From f6e988d6fdca673104b43461d92f723ea9072911 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Jun 2016 11:26:46 -0400 Subject: [PATCH] support zero-hops tunnels for destinations --- Tunnel.cpp | 28 ++++++++++++++++++++-------- Tunnel.h | 11 +++++++---- TunnelConfig.h | 5 +++++ TunnelPool.cpp | 21 +++++++++++++++------ 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/Tunnel.cpp b/Tunnel.cpp index 961cc97e..478b57bc 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -768,6 +768,22 @@ namespace tunnel return newTunnel; } + std::shared_ptr Tunnels::CreateInboundTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel) + { + if (config->IsEmpty ()) + return CreateZeroHopsInboundTunnel (); + else + return CreateTunnel(config, outboundTunnel); + } + + std::shared_ptr Tunnels::CreateOutboundTunnel (std::shared_ptr config) + { + if (config->IsEmpty ()) + return CreateZeroHopsOutboundTunnel (); + else + return CreateTunnel(config); + } + void Tunnels::AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel) { m_PendingInboundTunnels[replyMsgID] = tunnel; @@ -815,20 +831,22 @@ namespace tunnel } - void Tunnels::CreateZeroHopsInboundTunnel () + std::shared_ptr Tunnels::CreateZeroHopsInboundTunnel () { auto inboundTunnel = std::make_shared (); inboundTunnel->SetState (eTunnelStateEstablished); m_InboundTunnels.push_back (inboundTunnel); m_Tunnels[inboundTunnel->GetTunnelID ()] = inboundTunnel; + return inboundTunnel; } - void Tunnels::CreateZeroHopsOutboundTunnel () + std::shared_ptr Tunnels::CreateZeroHopsOutboundTunnel () { auto outboundTunnel = std::make_shared (); outboundTunnel->SetState (eTunnelStateEstablished); m_OutboundTunnels.push_back (outboundTunnel); // we don't insert into m_Tunnels + return outboundTunnel; } int Tunnels::GetTransitTunnelsExpirationTimeout () @@ -861,12 +879,6 @@ namespace tunnel // TODO: locking return m_OutboundTunnels.size(); } - -#ifdef ANDROID_ARM7A - template std::shared_ptr Tunnels::CreateTunnel(std::shared_ptr, std::shared_ptr); - template std::shared_ptr Tunnels::CreateTunnel(std::shared_ptr, std::shared_ptr); -#endif - } } diff --git a/Tunnel.h b/Tunnel.h index 43417e5d..5bc8b195 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -176,10 +176,10 @@ namespace tunnel void AddTransitTunnel (std::shared_ptr tunnel); void AddOutboundTunnel (std::shared_ptr newTunnel); void AddInboundTunnel (std::shared_ptr newTunnel); + std::shared_ptr CreateInboundTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel); + std::shared_ptr CreateOutboundTunnel (std::shared_ptr config); void PostTunnelData (std::shared_ptr msg); void PostTunnelData (const std::vector >& msgs); - template - std::shared_ptr CreateTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel = nullptr); void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel); void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr tunnel); std::shared_ptr CreateTunnelPool (int numInboundHops, @@ -189,6 +189,9 @@ namespace tunnel private: + template + std::shared_ptr CreateTunnel (std::shared_ptr config, std::shared_ptr outboundTunnel = nullptr); + template std::shared_ptr GetPendingTunnel (uint32_t replyMsgID, const std::map >& pendingTunnels); @@ -204,8 +207,8 @@ namespace tunnel void ManagePendingTunnels (PendingTunnels& pendingTunnels); void ManageTunnelPools (); - void CreateZeroHopsInboundTunnel (); - void CreateZeroHopsOutboundTunnel (); + std::shared_ptr CreateZeroHopsInboundTunnel (); + std::shared_ptr CreateZeroHopsOutboundTunnel (); private: diff --git a/TunnelConfig.h b/TunnelConfig.h index 0340254e..7546c9b2 100644 --- a/TunnelConfig.h +++ b/TunnelConfig.h @@ -159,6 +159,11 @@ namespace tunnel return num; } + bool IsEmpty () const + { + return !m_FirstHop; + } + virtual bool IsInbound () const { return m_FirstHop->isGateway; } virtual uint32_t GetTunnelID () const diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 5e7e8ec4..92e5f6ff 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -329,8 +329,9 @@ namespace tunnel bool TunnelPool::SelectPeers (std::vector >& peers, bool isInbound) { if (m_ExplicitPeers) return SelectExplicitPeers (peers, isInbound); - auto prevHop = i2p::context.GetSharedRouterInfo (); int numHops = isInbound ? m_NumInboundHops : m_NumOutboundHops; + if (numHops <= 0) return true; // peers is empty + auto prevHop = i2p::context.GetSharedRouterInfo (); if (i2p::transport::transports.GetNumPeers () > 25) { auto r = i2p::transport::transports.GetRandomPeer (); @@ -390,8 +391,10 @@ namespace tunnel if (SelectPeers (peers, true)) { std::reverse (peers.begin (), peers.end ()); - auto tunnel = tunnels.CreateTunnel (std::make_shared (peers), outboundTunnel); + auto tunnel = tunnels.CreateInboundTunnel (std::make_shared (peers), outboundTunnel); tunnel->SetTunnelPool (shared_from_this ()); + if (tunnel->IsEstablished ()) // zero hops + TunnelCreated (tunnel); } else LogPrint (eLogError, "Tunnels: Can't create inbound tunnel, no peers available"); @@ -403,8 +406,10 @@ namespace tunnel if (!outboundTunnel) outboundTunnel = tunnels.GetNextOutboundTunnel (); LogPrint (eLogDebug, "Tunnels: Re-creating destination inbound tunnel..."); - auto newTunnel = tunnels.CreateTunnel (std::make_shared(tunnel->GetPeers ()), outboundTunnel); + auto newTunnel = tunnels.CreateInboundTunnel (std::make_shared(tunnel->GetPeers ()), outboundTunnel); newTunnel->SetTunnelPool (shared_from_this()); + if (newTunnel->IsEstablished ()) // zero hops + TunnelCreated (newTunnel); } void TunnelPool::CreateOutboundTunnel () @@ -418,9 +423,11 @@ namespace tunnel std::vector > peers; if (SelectPeers (peers, false)) { - auto tunnel = tunnels.CreateTunnel ( + auto tunnel = tunnels.CreateOutboundTunnel ( std::make_shared (peers, inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ())); tunnel->SetTunnelPool (shared_from_this ()); + if (tunnel->IsEstablished ()) // zero hops + TunnelCreated (tunnel); } else LogPrint (eLogError, "Tunnels: Can't create outbound tunnel, no peers available"); @@ -437,10 +444,12 @@ namespace tunnel if (inboundTunnel) { LogPrint (eLogDebug, "Tunnels: Re-creating destination outbound tunnel..."); - auto newTunnel = tunnels.CreateTunnel ( + auto newTunnel = tunnels.CreateOutboundTunnel ( std::make_shared (tunnel->GetPeers (), inboundTunnel->GetNextTunnelID (), inboundTunnel->GetNextIdentHash ())); newTunnel->SetTunnelPool (shared_from_this ()); + if (newTunnel->IsEstablished ()) // zero hops + TunnelCreated (newTunnel); } else LogPrint (eLogDebug, "Tunnels: Can't re-create outbound tunnel, no inbound tunnels found"); @@ -449,7 +458,7 @@ namespace tunnel void TunnelPool::CreatePairedInboundTunnel (std::shared_ptr outboundTunnel) { LogPrint (eLogDebug, "Tunnels: Creating paired inbound tunnel..."); - auto tunnel = tunnels.CreateTunnel (std::make_shared(outboundTunnel->GetInvertedPeers ()), outboundTunnel); + auto tunnel = tunnels.CreateInboundTunnel (std::make_shared(outboundTunnel->GetInvertedPeers ()), outboundTunnel); tunnel->SetTunnelPool (shared_from_this ()); } }