diff --git a/libi2pd/Destination.cpp b/libi2pd/Destination.cpp index 06065640..f08ebaf9 100644 --- a/libi2pd/Destination.cpp +++ b/libi2pd/Destination.cpp @@ -213,7 +213,7 @@ namespace client return pool->Reconfigure(inLen, outLen, inQuant, outQuant); } - std::shared_ptr LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident) + std::shared_ptr LeaseSetDestination::FindLeaseSet (const i2p::data::IdentHash& ident) { std::shared_ptr remoteLS; { @@ -425,6 +425,7 @@ namespace client if (ls2->IsValid ()) { m_RemoteLeaseSets[ls2->GetIdentHash ()] = ls2; // ident is not key + m_RemoteLeaseSets[key] = ls2; // also store as key for next lookup leaseSet = ls2; } } @@ -594,7 +595,7 @@ namespace client auto s = shared_from_this (); RequestLeaseSet (GetIdentHash (), // "this" added due to bug in gcc 4.7-4.8 - [s,this](std::shared_ptr leaseSet) + [s,this](std::shared_ptr leaseSet) { if (leaseSet) { @@ -636,7 +637,7 @@ namespace client return true; } - bool LeaseSetDestination::RequestDestinationWithEncryptedLeaseSet (std::shared_ptr dest, RequestComplete requestComplete) + bool LeaseSetDestination::RequestDestinationWithEncryptedLeaseSet (std::shared_ptr dest, RequestComplete requestComplete) { if (!m_Pool || !IsReady ()) { @@ -644,10 +645,16 @@ namespace client m_Service.post ([requestComplete](void){requestComplete (nullptr);}); return false; } - auto blindedKey = std::make_shared(dest, i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); // always assume type 11 - i2p::data::IdentHash ident; - i2p::data::LeaseSet2::CalculateStoreHash (blindedKey, ident); - m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), ident, requestComplete, blindedKey)); + i2p::data::IdentHash storeKey; + i2p::data::LeaseSet2::CalculateStoreHash (dest, storeKey); + auto leaseSet = FindLeaseSet (storeKey); + if (leaseSet) + { + if (requestComplete) + m_Service.post ([requestComplete, leaseSet](void){requestComplete (leaseSet);}); + return true; + } + m_Service.post (std::bind (&LeaseSetDestination::RequestLeaseSet, shared_from_this (), storeKey, requestComplete, dest)); return true; } @@ -666,11 +673,10 @@ namespace client }); } - void LeaseSetDestination::CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr dest, bool notify) + void LeaseSetDestination::CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr dest, bool notify) { - auto blindedKey = std::make_shared(dest, i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519); // always assume type 11 i2p::data::IdentHash ident; - i2p::data::LeaseSet2::CalculateStoreHash (blindedKey, ident); + i2p::data::LeaseSet2::CalculateStoreHash (dest, ident); CancelDestinationRequest (ident, notify); } @@ -976,7 +982,7 @@ namespace client { auto s = GetSharedFromThis (); RequestDestination (dest, - [s, streamRequestComplete, port](std::shared_ptr ls) + [s, streamRequestComplete, port](std::shared_ptr ls) { if (ls) streamRequestComplete(s->CreateStream (ls, port)); @@ -986,6 +992,24 @@ namespace client } } + void ClientDestination::CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr dest, int port) + { + if (!streamRequestComplete) + { + LogPrint (eLogError, "Destination: request callback is not specified in CreateStream"); + return; + } + auto s = GetSharedFromThis (); + RequestDestinationWithEncryptedLeaseSet (dest, + [s, streamRequestComplete, port](std::shared_ptr ls) + { + if (ls) + streamRequestComplete(s->CreateStream (ls, port)); + else + streamRequestComplete (nullptr); + }); + } + std::shared_ptr ClientDestination::CreateStream (std::shared_ptr remote, int port) { if (m_StreamingDestination) diff --git a/libi2pd/Destination.h b/libi2pd/Destination.h index d2ef9f7a..b55a7490 100644 --- a/libi2pd/Destination.h +++ b/libi2pd/Destination.h @@ -108,11 +108,11 @@ namespace client boost::asio::io_service& GetService () { return m_Service; }; std::shared_ptr GetTunnelPool () { return m_Pool; }; bool IsReady () const { return m_LeaseSet && !m_LeaseSet->IsExpired () && m_Pool->GetOutboundTunnels ().size () > 0; }; - std::shared_ptr FindLeaseSet (const i2p::data::IdentHash& ident); + std::shared_ptr FindLeaseSet (const i2p::data::IdentHash& ident); bool RequestDestination (const i2p::data::IdentHash& dest, RequestComplete requestComplete = nullptr); - bool RequestDestinationWithEncryptedLeaseSet (std::shared_ptr dest, RequestComplete requestComplete = nullptr); + bool RequestDestinationWithEncryptedLeaseSet (std::shared_ptr dest, RequestComplete requestComplete = nullptr); void CancelDestinationRequest (const i2p::data::IdentHash& dest, bool notify = true); - void CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr dest, bool notify = true); + void CancelDestinationRequestWithEncryptedLeaseSet (std::shared_ptr dest, bool notify = true); // implements GarlicDestination std::shared_ptr GetLeaseSet (); @@ -213,6 +213,7 @@ namespace client std::shared_ptr GetStreamingDestination (int port = 0) const; // following methods operate with default streaming destination void CreateStream (StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash& dest, int port = 0); + void CreateStream (StreamRequestComplete streamRequestComplete, std::shared_ptr dest, int port = 0); std::shared_ptr CreateStream (std::shared_ptr remote, int port = 0); void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor); void StopAcceptingStreams ();