From c9ba7da0b0f8355f0757df3f0cc674b4ea8a05f0 Mon Sep 17 00:00:00 2001 From: orignal Date: Sun, 16 Mar 2014 16:03:20 -0400 Subject: [PATCH] outbound tunnel pool --- HTTPServer.cpp | 2 ++ Streaming.cpp | 2 +- Streaming.h | 1 + Tunnel.cpp | 8 ++++++- TunnelPool.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++-- TunnelPool.h | 11 +++++++--- 6 files changed, 74 insertions(+), 7 deletions(-) diff --git a/HTTPServer.cpp b/HTTPServer.cpp index c7d1fcaf..f02b0ba9 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -139,6 +139,8 @@ namespace util for (auto it: i2p::tunnel::tunnels.GetOutboundTunnels ()) { it->GetTunnelConfig ()->Print (s); + if (it->GetTunnelPool ()) + s << " " << "Pool"; s << " " << (int)it->GetNumSentBytes () << "
"; } diff --git a/Streaming.cpp b/Streaming.cpp index 6f623f4a..d365e57c 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -171,7 +171,7 @@ namespace stream CreateDataMessage (this, packet, size), m_LocalDestination->GetLeaseSet ()); if (!m_OutboundTunnel) - m_OutboundTunnel = i2p::tunnel::tunnels.GetNextOutboundTunnel (); + m_OutboundTunnel = m_LocalDestination->GetTunnelPool ()->GetNextOutboundTunnel (); auto leases = m_RemoteLeaseSet.GetNonExpiredLeases (); if (m_OutboundTunnel && !leases.empty ()) { diff --git a/Streaming.h b/Streaming.h index 8f0f289a..b0f7fda9 100644 --- a/Streaming.h +++ b/Streaming.h @@ -108,6 +108,7 @@ namespace stream const i2p::data::Keys& GetKeys () const { return m_Keys; }; const i2p::data::Identity& GetIdentity () const { return m_Identity; }; I2NPMessage * GetLeaseSet (); + i2p::tunnel::TunnelPool * GetTunnelPool () const { return m_Pool; }; void Sign (uint8_t * buf, int len, uint8_t * signature) const; Stream * CreateNewStream (const i2p::data::LeaseSet& remote); diff --git a/Tunnel.cpp b/Tunnel.cpp index e9e59b86..5d93c50a 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -390,13 +390,16 @@ namespace tunnel if (ts > (*it)->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) { LogPrint ("Tunnel ", (*it)->GetTunnelID (), " expired"); + auto pool = (*it)->GetTunnelPool (); + if (pool) + pool->TunnelExpired (*it); it = m_OutboundTunnels.erase (it); } else it++; } - if (m_OutboundTunnels.size () < 10) + if (m_OutboundTunnels.size () < 15) // TODO: store exploratory tunnels explicitly { // trying to create one more oubound tunnel if (m_InboundTunnels.empty ()) return; @@ -520,6 +523,9 @@ namespace tunnel void Tunnels::AddOutboundTunnel (OutboundTunnel * newTunnel) { m_OutboundTunnels.push_back (newTunnel); + auto pool = newTunnel->GetTunnelPool (); + if (pool) + pool->TunnelCreated (newTunnel); } void Tunnels::AddInboundTunnel (InboundTunnel * newTunnel) diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 37854db2..6d6516ec 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -11,7 +11,7 @@ namespace i2p namespace tunnel { TunnelPool::TunnelPool (i2p::data::LocalDestination * localDestination, int numTunnels): - m_LocalDestination (localDestination), m_NumTunnels (numTunnels) + m_LocalDestination (localDestination), m_NumTunnels (numTunnels), m_LastOutboundTunnel (nullptr) { CryptoPP::AutoSeededRandomPool rnd; CryptoPP::DH dh (i2p::crypto::elgp, i2p::crypto::elgg); @@ -22,6 +22,8 @@ namespace tunnel { for (auto it: m_InboundTunnels) it->SetTunnelPool (nullptr); + for (auto it: m_OutboundTunnels) + it->SetTunnelPool (nullptr); } void TunnelPool::TunnelCreated (InboundTunnel * createdTunnel) @@ -37,6 +39,16 @@ namespace tunnel if (m_LocalDestination) m_LocalDestination->UpdateLeaseSet (); } + + void TunnelPool::TunnelCreated (OutboundTunnel * createdTunnel) + { + m_OutboundTunnels.insert (createdTunnel); + } + + void TunnelPool::TunnelExpired (OutboundTunnel * expiredTunnel) + { + m_OutboundTunnels.erase (expiredTunnel); + } std::vector TunnelPool::GetInboundTunnels (int num) const { @@ -51,16 +63,37 @@ namespace tunnel return v; } + OutboundTunnel * TunnelPool::GetNextOutboundTunnel () + { + if (m_OutboundTunnels.empty ()) return nullptr; + auto tunnel = *m_OutboundTunnels.begin (); + if (m_LastOutboundTunnel && tunnel == m_LastOutboundTunnel) + { + for (auto it: m_OutboundTunnels) + if (it != m_LastOutboundTunnel) + { + tunnel = it; + break; + } + } + m_LastOutboundTunnel = tunnel; + return tunnel; + } + void TunnelPool::CreateTunnels () { int num = m_InboundTunnels.size (); for (int i = num; i < m_NumTunnels; i++) CreateInboundTunnel (); + num = m_OutboundTunnels.size (); + for (int i = num; i < m_NumTunnels; i++) + CreateOutboundTunnel (); } void TunnelPool::CreateInboundTunnel () { - OutboundTunnel * outboundTunnel = tunnels.GetNextOutboundTunnel (); + OutboundTunnel * outboundTunnel = m_OutboundTunnels.size () > 0 ? + *m_OutboundTunnels.begin () : tunnels.GetNextOutboundTunnel (); LogPrint ("Creating destination inbound tunnel..."); auto firstHop = i2p::data::netdb.GetRandomRouter (outboundTunnel ? outboundTunnel->GetEndpointRouter () : nullptr); auto secondHop = i2p::data::netdb.GetRandomRouter (firstHop); @@ -75,5 +108,25 @@ namespace tunnel outboundTunnel); tunnel->SetTunnelPool (this); } + + void TunnelPool::CreateOutboundTunnel () + { + InboundTunnel * inboundTunnel = m_InboundTunnels.size () > 0 ? + *m_InboundTunnels.begin () : tunnels.GetNextInboundTunnel (); + if (inboundTunnel) + { + LogPrint ("Creating destination outbound tunnel..."); + auto firstHop = i2p::data::netdb.GetRandomRouter (&i2p::context.GetRouterInfo ()); + auto secondHop = i2p::data::netdb.GetRandomRouter (firstHop); + auto * tunnel = tunnels.CreateTunnel ( + new TunnelConfig (std::vector + { + firstHop, + secondHop + }, + inboundTunnel->GetTunnelConfig ())); + tunnel->SetTunnelPool (this); + } + } } } diff --git a/TunnelPool.h b/TunnelPool.h index 8dad4051..f8b6aab5 100644 --- a/TunnelPool.h +++ b/TunnelPool.h @@ -29,19 +29,24 @@ namespace tunnel void CreateTunnels (); void TunnelCreated (InboundTunnel * createdTunnel); void TunnelExpired (InboundTunnel * expiredTunnel); + void TunnelCreated (OutboundTunnel * createdTunnel); + void TunnelExpired (OutboundTunnel * expiredTunnel); std::vector GetInboundTunnels (int num) const; - + OutboundTunnel * GetNextOutboundTunnel (); + private: void CreateInboundTunnel (); - + void CreateOutboundTunnel (); + private: uint8_t m_EncryptionPublicKey[256], m_EncryptionPrivateKey[256]; i2p::data::LocalDestination * m_LocalDestination; int m_NumTunnels; std::set m_InboundTunnels; // recent tunnel appears first - + std::set m_OutboundTunnels; + OutboundTunnel * m_LastOutboundTunnel; }; } }