diff --git a/Destination.cpp b/Destination.cpp index 5f6c8706..eb30be14 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -43,7 +43,7 @@ namespace client } } } - m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (*this, inboundTunnelLen, outboundTunnelLen); + m_Pool = i2p::tunnel::tunnels.CreateTunnelPool (this, inboundTunnelLen, outboundTunnelLen); if (m_IsPublic) LogPrint (eLogInfo, "Local address ", GetIdentHash ().ToBase32 (), ".b32.i2p created"); m_StreamingDestination = new i2p::stream::StreamingDestination (*this); // TODO: @@ -85,6 +85,7 @@ namespace client m_Service = new boost::asio::io_service; m_PublishConfirmationTimer = new boost::asio::deadline_timer (*m_Service); m_Work = new boost::asio::io_service::work (*m_Service); + m_Pool->SetLocalDestination (this); m_Pool->SetActive (true); m_IsRunning = true; m_Thread = new std::thread (std::bind (&ClientDestination::Run, this)); @@ -101,7 +102,10 @@ namespace client delete d; } if (m_Pool) + { + m_Pool->SetLocalDestination (nullptr); i2p::tunnel::tunnels.StopTunnelPool (m_Pool); + } m_IsRunning = false; if (m_Service) m_Service->stop (); diff --git a/I2NPProtocol.cpp b/I2NPProtocol.cpp index 6668fe2a..84fbeafe 100644 --- a/I2NPProtocol.cpp +++ b/I2NPProtocol.cpp @@ -160,8 +160,8 @@ namespace i2p rnd.GenerateBlock (buf, 32); // key buf[32] = 1; // 1 tag rnd.GenerateBlock (buf + 33, 32); // tag - if (pool) - pool->GetLocalDestination ().SubmitSessionKey (buf, buf + 33); // introduce new key-tag to garlic engine + if (pool && pool->GetLocalDestination ()) + pool->GetLocalDestination ()->SubmitSessionKey (buf, buf + 33); // introduce new key-tag to garlic engine else LogPrint ("Destination for encrypteed reply not specified"); buf += 65; @@ -563,7 +563,7 @@ namespace i2p case eI2NPGarlic: LogPrint ("Garlic"); if (msg->from && msg->from->GetTunnelPool ()) - msg->from->GetTunnelPool ()->GetLocalDestination ().ProcessGarlicMessage (msg); + msg->from->GetTunnelPool ()->ProcessGarlicMessage (msg); else i2p::context.ProcessGarlicMessage (msg); break; diff --git a/LeaseSet.cpp b/LeaseSet.cpp index 467f3145..15c2ded3 100644 --- a/LeaseSet.cpp +++ b/LeaseSet.cpp @@ -22,11 +22,17 @@ namespace data LeaseSet::LeaseSet (const i2p::tunnel::TunnelPool& pool) { // header - const i2p::data::LocalDestination& localDestination = pool.GetLocalDestination (); - m_BufferLen = localDestination.GetIdentity ().ToBuffer (m_Buffer, MAX_LS_BUFFER_SIZE); - memcpy (m_Buffer + m_BufferLen, localDestination.GetEncryptionPublicKey (), 256); + const i2p::data::LocalDestination * localDestination = pool.GetLocalDestination (); + if (!localDestination) + { + m_BufferLen = 0; + LogPrint (eLogError, "Destination for local LeaseSet doesn't exist"); + return; + } + m_BufferLen = localDestination->GetIdentity ().ToBuffer (m_Buffer, MAX_LS_BUFFER_SIZE); + memcpy (m_Buffer + m_BufferLen, localDestination->GetEncryptionPublicKey (), 256); m_BufferLen += 256; - auto signingKeyLen = localDestination.GetIdentity ().GetSigningPublicKeyLen (); + auto signingKeyLen = localDestination->GetIdentity ().GetSigningPublicKeyLen (); memset (m_Buffer + m_BufferLen, 0, signingKeyLen); m_BufferLen += signingKeyLen; auto tunnels = pool.GetInboundTunnels (5); // 5 tunnels maximum @@ -44,8 +50,8 @@ namespace data m_BufferLen += sizeof (Lease); } // signature - localDestination.Sign (m_Buffer, m_BufferLen, m_Buffer + m_BufferLen); - m_BufferLen += localDestination.GetIdentity ().GetSignatureLen (); + localDestination->Sign (m_Buffer, m_BufferLen, m_Buffer + m_BufferLen); + m_BufferLen += localDestination->GetIdentity ().GetSignatureLen (); LogPrint ("Local LeaseSet of ", tunnels.size (), " leases created"); ReadFromBuffer (); diff --git a/NetDb.cpp b/NetDb.cpp index b5149b48..fc641c45 100644 --- a/NetDb.cpp +++ b/NetDb.cpp @@ -29,8 +29,8 @@ namespace data &m_ExcludedPeers, m_IsLeaseSet, m_Pool); if (m_IsLeaseSet) // wrap lookup message into garlic { - if (m_Pool) - msg = m_Pool->GetLocalDestination ().WrapMessage (*router, msg); + if (m_Pool && m_Pool->GetLocalDestination ()) + msg = m_Pool->GetLocalDestination ()->WrapMessage (*router, msg); else LogPrint ("Can't create garlic message without destination"); } diff --git a/Tunnel.cpp b/Tunnel.cpp index 8e52020d..b61551d1 100644 --- a/Tunnel.cpp +++ b/Tunnel.cpp @@ -287,7 +287,7 @@ namespace tunnel return tunnel; } - TunnelPool * Tunnels::CreateTunnelPool (i2p::garlic::GarlicDestination& localDestination, int numInboundHops, int numOutboundHops) + TunnelPool * Tunnels::CreateTunnelPool (i2p::garlic::GarlicDestination * localDestination, int numInboundHops, int numOutboundHops) { auto pool = new TunnelPool (localDestination, numInboundHops, numOutboundHops); std::unique_lock l(m_PoolsMutex); @@ -513,7 +513,7 @@ namespace tunnel LogPrint ("Creating zero hops inbound tunnel..."); CreateZeroHopsInboundTunnel (); if (!m_ExploratoryPool) - m_ExploratoryPool = CreateTunnelPool (i2p::context, 2, 2); // 2-hop exploratory + m_ExploratoryPool = CreateTunnelPool (&i2p::context, 2, 2); // 2-hop exploratory return; } diff --git a/Tunnel.h b/Tunnel.h index a8dc77cf..d5c48ee7 100644 --- a/Tunnel.h +++ b/Tunnel.h @@ -129,7 +129,7 @@ namespace tunnel void PostTunnelData (I2NPMessage * msg); template TTunnel * CreateTunnel (TunnelConfig * config, OutboundTunnel * outboundTunnel = 0); - TunnelPool * CreateTunnelPool (i2p::garlic::GarlicDestination& localDestination, int numInboundHops, int numOuboundHops); + TunnelPool * CreateTunnelPool (i2p::garlic::GarlicDestination * localDestination, int numInboundHops, int numOuboundHops); void DeleteTunnelPool (TunnelPool * pool); void StopTunnelPool (TunnelPool * pool); diff --git a/TunnelPool.cpp b/TunnelPool.cpp index 0adfad09..30441cbc 100644 --- a/TunnelPool.cpp +++ b/TunnelPool.cpp @@ -10,7 +10,7 @@ namespace i2p { namespace tunnel { - TunnelPool::TunnelPool (i2p::garlic::GarlicDestination& localDestination, int numInboundHops, int numOutboundHops, int numTunnels): + TunnelPool::TunnelPool (i2p::garlic::GarlicDestination * localDestination, int numInboundHops, int numOutboundHops, int numTunnels): m_LocalDestination (localDestination), m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops), m_NumTunnels (numTunnels), m_IsActive (true) { @@ -45,7 +45,8 @@ namespace tunnel std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.insert (createdTunnel); } - m_LocalDestination.SetLeaseSetUpdated (); + if (m_LocalDestination) + m_LocalDestination->SetLeaseSetUpdated (); } void TunnelPool::TunnelExpired (InboundTunnel * expiredTunnel) @@ -183,7 +184,8 @@ namespace tunnel std::unique_lock l(m_InboundTunnelsMutex); m_InboundTunnels.erase (it.second.second); } - m_LocalDestination.SetLeaseSetUpdated (); + if (m_LocalDestination) + m_LocalDestination->SetLeaseSetUpdated (); } else it.second.second->SetState (eTunnelStateTestFailed); @@ -217,6 +219,17 @@ namespace tunnel } } + void TunnelPool::ProcessGarlicMessage (I2NPMessage * msg) + { + if (m_LocalDestination) + m_LocalDestination->ProcessGarlicMessage (msg); + else + { + LogPrint (eLogWarning, "Local destination doesn't exist. Dropped"); + DeleteI2NPMessage (msg); + } + } + void TunnelPool::ProcessDeliveryStatus (I2NPMessage * msg) { I2NPDeliveryStatusMsg * deliveryStatus = (I2NPDeliveryStatusMsg *)msg->GetPayload (); @@ -233,12 +246,20 @@ namespace tunnel DeleteI2NPMessage (msg); } else - m_LocalDestination.ProcessDeliveryStatusMessage (msg); + { + if (m_LocalDestination) + m_LocalDestination->ProcessDeliveryStatusMessage (msg); + else + { + LogPrint (eLogWarning, "Local destination doesn't exist. Dropped"); + DeleteI2NPMessage (msg); + } + } } std::shared_ptr TunnelPool::SelectNextHop (std::shared_ptr prevHop) const { - bool isExploratory = (&m_LocalDestination == &i2p::context); // TODO: implement it better + bool isExploratory = (m_LocalDestination == &i2p::context); // TODO: implement it better auto hop = isExploratory ? i2p::data::netdb.GetRandomRouter (prevHop): i2p::data::netdb.GetHighBandwidthRandomRouter (prevHop); diff --git a/TunnelPool.h b/TunnelPool.h index 9415386f..b2d75950 100644 --- a/TunnelPool.h +++ b/TunnelPool.h @@ -26,10 +26,11 @@ namespace tunnel { public: - TunnelPool (i2p::garlic::GarlicDestination& localDestination, int numInboundHops, int numOutboundHops, int numTunnels = 5); + TunnelPool (i2p::garlic::GarlicDestination * localDestination, int numInboundHops, int numOutboundHops, int numTunnels = 5); ~TunnelPool (); - i2p::garlic::GarlicDestination& GetLocalDestination () const { return m_LocalDestination; }; + i2p::garlic::GarlicDestination * GetLocalDestination () const { return m_LocalDestination; }; + void SetLocalDestination (i2p::garlic::GarlicDestination * destination) { m_LocalDestination = destination; }; void CreateTunnels (); void TunnelCreated (InboundTunnel * createdTunnel); @@ -41,6 +42,7 @@ namespace tunnel InboundTunnel * GetNextInboundTunnel (InboundTunnel * suggested = nullptr) const; void TestTunnels (); + void ProcessGarlicMessage (I2NPMessage * msg); void ProcessDeliveryStatus (I2NPMessage * msg); bool IsActive () const { return m_IsActive; }; @@ -60,7 +62,7 @@ namespace tunnel private: - i2p::garlic::GarlicDestination& m_LocalDestination; + i2p::garlic::GarlicDestination * m_LocalDestination; int m_NumInboundHops, m_NumOutboundHops, m_NumTunnels; mutable std::mutex m_InboundTunnelsMutex; std::set m_InboundTunnels; // recent tunnel appears first