diff --git a/HTTPServer.cpp b/HTTPServer.cpp index e8620f09..b1f03e86 100644 --- a/HTTPServer.cpp +++ b/HTTPServer.cpp @@ -148,6 +148,17 @@ namespace util s << " " << (int)it.second->GetNumReceivedBytes () << "
"; } + s << "

Tunnel pools

"; + for (auto it: i2p::tunnel::tunnels.GetTunnelPools ()) + { + for (auto it1: it->GetInboundTunnels ()) + { + it1->GetTunnelConfig ()->Print (s); + s << " " << (int)it1->GetNumReceivedBytes () << "
"; + } + s << "
"; + } + s << "

Transit tunnels

"; for (auto it: i2p::tunnel::tunnels.GetTransitTunnels ()) { diff --git a/Streaming.cpp b/Streaming.cpp index cbe6575b..0bd88f66 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -300,7 +300,7 @@ namespace stream StreamingDestination * sharedLocalDestination = nullptr; - StreamingDestination::StreamingDestination (): m_TunnelPool (this), m_LeaseSet (nullptr) + StreamingDestination::StreamingDestination (): m_LeaseSet (nullptr) { // TODO: read from file later m_Keys = i2p::data::CreateRandomKeys (); @@ -308,6 +308,7 @@ namespace stream m_IdentHash = i2p::data::CalculateIdentHash (m_Identity); m_SigningPrivateKey.Initialize (i2p::crypto::dsap, i2p::crypto::dsaq, i2p::crypto::dsag, CryptoPP::Integer (m_Keys.signingPrivateKey, 20)); + i2p::tunnel::tunnels.CreateTunnelPool (this); } StreamingDestination::~StreamingDestination () @@ -316,16 +317,6 @@ namespace stream DeleteI2NPMessage (m_LeaseSet); } - void StreamingDestination::Start () - { - m_TunnelPool.CreateTunnels (); - } - - void StreamingDestination::Stop () - { - // TODO: - } - void StreamingDestination::HandleNextPacket (Packet * packet) { uint32_t sendStreamID = packet->GetSendStreamID (); diff --git a/Streaming.h b/Streaming.h index 60044a6b..e4438e0c 100644 --- a/Streaming.h +++ b/Streaming.h @@ -11,7 +11,6 @@ #include "LeaseSet.h" #include "I2NPProtocol.h" #include "Tunnel.h" -#include "TunnelPool.h" namespace i2p { @@ -103,9 +102,7 @@ namespace stream public: StreamingDestination (); - ~StreamingDestination (); - void Start (); - void Stop (); + ~StreamingDestination (); const i2p::data::Keys& GetKeys () const { return m_Keys; }; const i2p::data::Identity& GetIdentity () const { return m_Identity; }; @@ -130,7 +127,6 @@ namespace stream i2p::data::Identity m_Identity; i2p::data::IdentHash m_IdentHash; - i2p::tunnel::TunnelPool m_TunnelPool; I2NPMessage * m_LeaseSet; CryptoPP::DSA::PrivateKey m_SigningPrivateKey; diff --git a/Tunnel.cpp b/Tunnel.cpp index 1c03405e..8c58f8ae 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -186,6 +186,10 @@ namespace tunnel for (auto& it : m_PendingTunnels) delete it.second; m_PendingTunnels.clear (); + + for (auto& it: m_Pools) + delete it; + m_Pools.clear (); } InboundTunnel * Tunnels::GetInboundTunnel (uint32_t tunnelID) @@ -268,6 +272,11 @@ namespace tunnel } return tunnel;*/ } + + void Tunnels::CreateTunnelPool (i2p::data::LocalDestination * localDestination) + { + m_Pools.push_back (new TunnelPool (localDestination)); + } void Tunnels::AddTransitTunnel (TransitTunnel * tunnel) { @@ -343,9 +352,6 @@ namespace tunnel for (auto& it : m_PendingTunnels) { LogPrint ("Pending tunnel build request ", it.first, " has not been responded. Deleted"); - auto pool = it.second->GetTunnelPool (); - if (pool) - pool->TunnelCreationFailed (it.second); delete it.second; } m_PendingTunnels.clear (); @@ -353,6 +359,7 @@ namespace tunnel ManageInboundTunnels (); ManageOutboundTunnels (); ManageTransitTunnels (); + ManageTunnelPools (); /* if (!m_IsTunnelCreated) { @@ -421,9 +428,6 @@ namespace tunnel if (ts > it->second->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) { LogPrint ("Tunnel ", it->second->GetTunnelID (), " expired"); - auto pool = it->second->GetTunnelPool (); - if (pool) - pool->TunnelExpired (it->second); it = m_InboundTunnels.erase (it); } else @@ -480,6 +484,12 @@ namespace tunnel it++; } } + + void Tunnels::ManageTunnelPools () + { + for (auto& it: m_Pools) + it->ManageTunnels (); + } void Tunnels::PostTunnelData (I2NPMessage * msg) { @@ -503,15 +513,15 @@ namespace tunnel void Tunnels::AddInboundTunnel (InboundTunnel * newTunnel) { - m_InboundTunnels[newTunnel->GetTunnelID ()] = newTunnel; auto pool = newTunnel->GetTunnelPool (); - if (pool) - pool->TunnelCreated (newTunnel); - else + if (!pool) { + m_InboundTunnels[newTunnel->GetTunnelID ()] = newTunnel; // build symmetric outbound tunnel CreateTunnel (newTunnel->GetTunnelConfig ()->Invert (), GetNextOutboundTunnel ()); } + else + pool->TunnelCreated (newTunnel); } diff --git a/Tunnel.h b/Tunnel.h index 2200dc2e..6a00aa0e 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -105,9 +105,8 @@ namespace tunnel Tunnels (); ~Tunnels (); - void Start (); - void Stop (); + void Stop (); InboundTunnel * GetInboundTunnel (uint32_t tunnelID); Tunnel * GetPendingTunnel (uint32_t replyMsgID); @@ -121,6 +120,7 @@ namespace tunnel void PostTunnelData (I2NPMessage * msg); template TTunnel * CreateTunnel (TunnelConfig * config, OutboundTunnel * outboundTunnel = 0); + void CreateTunnelPool (i2p::data::LocalDestination * localDestination); OutboundTunnel * CreateOneHopOutboundTestTunnel (InboundTunnel * replyTunnel); InboundTunnel * CreateOneHopInboundTestTunnel (OutboundTunnel * outboundTunnel = 0); @@ -134,6 +134,7 @@ namespace tunnel void ManageOutboundTunnels (); void ManageInboundTunnels (); void ManageTransitTunnels (); + void ManageTunnelPools (); void CreateZeroHopsInboundTunnel (); @@ -147,6 +148,7 @@ namespace tunnel std::map m_InboundTunnels; std::list m_OutboundTunnels; std::map m_TransitTunnels; + std::list m_Pools; i2p::util::Queue m_Queue; public: @@ -155,6 +157,7 @@ namespace tunnel const decltype(m_OutboundTunnels)& GetOutboundTunnels () const { return m_OutboundTunnels; }; const decltype(m_InboundTunnels)& GetInboundTunnels () const { return m_InboundTunnels; }; const decltype(m_TransitTunnels)& GetTransitTunnels () const { return m_TransitTunnels; }; + const decltype(m_Pools)& GetTunnelPools () const { return m_Pools; }; }; extern Tunnels tunnels; diff --git a/TunnelPool.cpp b/TunnelPool.cpp index c6e36ca3..8860c4b8 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -1,5 +1,6 @@ #include "Tunnel.h" #include "NetDb.h" +#include "Timestamp.h" #include "TunnelPool.h" namespace i2p @@ -14,19 +15,7 @@ namespace tunnel TunnelPool::~TunnelPool () { for (auto it: m_InboundTunnels) - it->SetTunnelPool (nullptr); - } - - void TunnelPool::TunnelCreationFailed (Tunnel * failedTunnel) - { - CreateInboundTunnel (); - } - - void TunnelPool::TunnelExpired (InboundTunnel * expiredTunnel) - { - CreateInboundTunnel (); - if (m_Owner) - m_Owner->UpdateLeaseSet (); + delete it; } void TunnelPool::TunnelCreated (InboundTunnel * createdTunnel) @@ -49,7 +38,8 @@ namespace tunnel void TunnelPool::CreateTunnels () { - for (int i = 0; i < m_NumTunnels; i++) + int num = m_InboundTunnels.size (); + for (int i = num; i < m_NumTunnels; i++) CreateInboundTunnel (); } @@ -67,5 +57,25 @@ namespace tunnel outboundTunnel); tunnel->SetTunnelPool (this); } + + void TunnelPool::ManageTunnels () + { + uint64_t ts = i2p::util::GetSecondsSinceEpoch (); + bool isLeaseSetUpdated = false; + for (auto it = m_InboundTunnels.begin (); it != m_InboundTunnels.end ();) + { + if (ts > (*it)->GetCreationTime () + TUNNEL_EXPIRATION_TIMEOUT) + { + LogPrint ("Destination tunnel ", (*it)->GetTunnelID (), " expired"); + m_InboundTunnels.erase (it++); + isLeaseSetUpdated = true; + } + else + ++it; + } + CreateTunnels (); + if (isLeaseSetUpdated && m_Owner) + m_Owner->UpdateLeaseSet (); + } } } diff --git a/TunnelPool.h b/TunnelPool.h index 6feb2afc..e6017e64 100644 --- a/TunnelPool.h +++ b/TunnelPool.h @@ -24,11 +24,9 @@ namespace tunnel ~TunnelPool (); void CreateTunnels (); - std::vector GetInboundTunnels (int num) const; - - void TunnelCreationFailed (Tunnel * failedTunnel); - void TunnelExpired (InboundTunnel * expiredTunnel); void TunnelCreated (InboundTunnel * createdTunnel); + std::vector GetInboundTunnels (int num) const; + void ManageTunnels (); private: @@ -39,6 +37,11 @@ namespace tunnel i2p::data::LocalDestination * m_Owner; int m_NumTunnels; std::set m_InboundTunnels; // recent tunnel appears first + + public: + + // for HTTP only + const decltype(m_InboundTunnels)& GetInboundTunnels () const { return m_InboundTunnels; }; }; } }