diff --git a/Identity.h b/Identity.h index 10af227c..6552fa38 100644 --- a/Identity.h +++ b/Identity.h @@ -104,6 +104,13 @@ namespace data mutable i2p::crypto::ElGamalEncryption * m_ElGamalEncryption; // use lazy initialization }; + + class LocalDestination + { + public: + + virtual void UpdateLeaseSet () = 0; // LeaseSet must be update + }; } } diff --git a/Streaming.cpp b/Streaming.cpp index 6caa2a0f..cbe6575b 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -300,7 +300,7 @@ namespace stream StreamingDestination * sharedLocalDestination = nullptr; - StreamingDestination::StreamingDestination (): m_LeaseSet (nullptr) + StreamingDestination::StreamingDestination (): m_TunnelPool (this), m_LeaseSet (nullptr) { // TODO: read from file later m_Keys = i2p::data::CreateRandomKeys (); @@ -315,7 +315,17 @@ namespace stream if (m_LeaseSet) 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 4e33d111..60044a6b 100644 --- a/Streaming.h +++ b/Streaming.h @@ -11,6 +11,7 @@ #include "LeaseSet.h" #include "I2NPProtocol.h" #include "Tunnel.h" +#include "TunnelPool.h" namespace i2p { @@ -97,22 +98,27 @@ namespace stream i2p::tunnel::OutboundTunnel * m_OutboundTunnel; }; - class StreamingDestination + class StreamingDestination: public i2p::data::LocalDestination { public: StreamingDestination (); ~StreamingDestination (); - + void Start (); + void Stop (); + const i2p::data::Keys& GetKeys () const { return m_Keys; }; const i2p::data::Identity& GetIdentity () const { return m_Identity; }; I2NPMessage * GetLeaseSet (); - void Sign (uint8_t * buf, int len, uint8_t * signature) const; - + void Sign (uint8_t * buf, int len, uint8_t * signature) const; + Stream * CreateNewStream (const i2p::data::LeaseSet& remote); void DeleteStream (Stream * stream); void HandleNextPacket (Packet * packet); + // implements LocalDestination + void UpdateLeaseSet () {}; // TODO: + private: I2NPMessage * CreateLeaseSet () const; @@ -124,6 +130,7 @@ 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 df1229a5..1c03405e 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -504,8 +504,14 @@ namespace tunnel void Tunnels::AddInboundTunnel (InboundTunnel * newTunnel) { m_InboundTunnels[newTunnel->GetTunnelID ()] = newTunnel; - // build symmetric outbound tunnel - CreateTunnel (newTunnel->GetTunnelConfig ()->Invert (), GetNextOutboundTunnel ()); + auto pool = newTunnel->GetTunnelPool (); + if (pool) + pool->TunnelCreated (newTunnel); + else + { + // build symmetric outbound tunnel + CreateTunnel (newTunnel->GetTunnelConfig ()->Invert (), GetNextOutboundTunnel ()); + } } diff --git a/TunnelBase.h b/TunnelBase.h index 6be902ca..24704d46 100644 --- a/TunnelBase.h +++ b/TunnelBase.h @@ -48,6 +48,17 @@ namespace tunnel uint32_t m_CreationTime; // seconds since epoch }; + + struct TunnelCreationTimeCmp + { + bool operator() (const TunnelBase * t1, const TunnelBase * t2) const + { + if (t1->GetCreationTime () != t2->GetCreationTime ()) + return t1->GetCreationTime () > t2->GetCreationTime (); + else + return t1 < t2; + }; + }; } } diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 2acdef6c..c6e36ca3 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -1,11 +1,13 @@ #include "Tunnel.h" +#include "NetDb.h" #include "TunnelPool.h" namespace i2p { namespace tunnel { - TunnelPool::TunnelPool () + TunnelPool::TunnelPool (i2p::data::LocalDestination * owner, int numTunnels): + m_Owner (owner), m_NumTunnels (numTunnels) { } @@ -17,10 +19,53 @@ namespace tunnel void TunnelPool::TunnelCreationFailed (Tunnel * failedTunnel) { + CreateInboundTunnel (); } void TunnelPool::TunnelExpired (InboundTunnel * expiredTunnel) { + CreateInboundTunnel (); + if (m_Owner) + m_Owner->UpdateLeaseSet (); + } + + void TunnelPool::TunnelCreated (InboundTunnel * createdTunnel) + { + m_InboundTunnels.insert (createdTunnel); + } + + std::vector TunnelPool::GetInboundTunnels (int num) const + { + std::vector v; + int i = 0; + for (auto it : m_InboundTunnels) + { + if (i >= num) break; + v.push_back (it); + i++; + } + return v; + } + + void TunnelPool::CreateTunnels () + { + for (int i = 0; i < m_NumTunnels; i++) + CreateInboundTunnel (); + } + + void TunnelPool::CreateInboundTunnel () + { + OutboundTunnel * outboundTunnel = tunnels.GetNextOutboundTunnel (); + LogPrint ("Creating destination inbound tunnel..."); + auto firstHop = i2p::data::netdb.GetRandomRouter (outboundTunnel ? outboundTunnel->GetEndpointRouter () : nullptr); + auto * tunnel = tunnels.CreateTunnel ( + new TunnelConfig (std::vector + { + firstHop, + i2p::data::netdb.GetRandomRouter (firstHop) + }), + outboundTunnel); + tunnel->SetTunnelPool (this); } } } diff --git a/TunnelPool.h b/TunnelPool.h index c4b7e347..6feb2afc 100644 --- a/TunnelPool.h +++ b/TunnelPool.h @@ -1,8 +1,12 @@ #ifndef TUNNEL_POOL__ #define TUNNEL_POOL__ -#include +#include +#include +#include "Identity.h" #include "LeaseSet.h" +#include "I2NPProtocol.h" +#include "TunnelBase.h" namespace i2p { @@ -16,15 +20,25 @@ namespace tunnel { public: - TunnelPool (); + TunnelPool (i2p::data::LocalDestination * owner, int numTunnels = 5); ~TunnelPool (); + void CreateTunnels (); + std::vector GetInboundTunnels (int num) const; + void TunnelCreationFailed (Tunnel * failedTunnel); void TunnelExpired (InboundTunnel * expiredTunnel); + void TunnelCreated (InboundTunnel * createdTunnel); + + private: + + void CreateInboundTunnel (); private: - std::list m_InboundTunnels; + i2p::data::LocalDestination * m_Owner; + int m_NumTunnels; + std::set m_InboundTunnels; // recent tunnel appears first }; } }