From e5503c51b49d6262ab1784773d5891c6948922f1 Mon Sep 17 00:00:00 2001 From: "Francisco Blas (klondike) Izquierdo Riera" Date: Fri, 2 Jan 2015 00:56:26 +0100 Subject: [PATCH] Allow for easy stream creation at LocalDestination (for now it's only synchronous) --- Destination.cpp | 40 +++++++++++++++++++++++++++++++++++++++- Destination.h | 3 +++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/Destination.cpp b/Destination.cpp index 307e803a..5e1dd2c8 100644 --- a/Destination.cpp +++ b/Destination.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include "Log.h" @@ -6,6 +7,7 @@ #include "Timestamp.h" #include "NetDb.h" #include "Destination.h" +#include "ClientContext.h" namespace i2p { @@ -383,12 +385,48 @@ namespace client } } + std::shared_ptr ClientDestination::CreateStream (const std::string& dest, int port) { + i2p::data::IdentHash identHash; + if (i2p::client::context.GetAddressBook ().GetIdentHash (dest, identHash)) + return CreateStream (identHash, port); + else + { + LogPrint (eLogWarning, "Remote destination ", dest, " not found"); + return nullptr; + } + } + + std::shared_ptr ClientDestination::CreateStream (const i2p::data::IdentHash& dest, int port) { + const i2p::data::LeaseSet * leaseSet = FindLeaseSet (dest); + if (!leaseSet) + { + bool found = false; + std::condition_variable newDataReceived; + std::mutex newDataReceivedMutex; + std::unique_lock l(newDataReceivedMutex); + RequestDestination (dest, + [&newDataReceived, &found](bool success) + { + found = success; + newDataReceived.notify_all (); + }); + if (newDataReceived.wait_for (l, std::chrono::seconds (STREAM_REQUEST_TIMEOUT)) == std::cv_status::timeout) + LogPrint (eLogError, "Subscription LeseseSet request timeout expired"); + if (found) + leaseSet = FindLeaseSet (dest); + } + if (leaseSet) + return CreateStream (*leaseSet, port); + else + return nullptr; + } + std::shared_ptr ClientDestination::CreateStream (const i2p::data::LeaseSet& remote, int port) { if (m_StreamingDestination) return m_StreamingDestination->CreateNewOutgoingStream (remote, port); return nullptr; - } + } void ClientDestination::AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor) { diff --git a/Destination.h b/Destination.h index 66836725..1f42dba3 100644 --- a/Destination.h +++ b/Destination.h @@ -35,6 +35,7 @@ namespace client const int DEFAULT_INBOUND_TUNNEL_LENGTH = 3; const char I2CP_PARAM_OUTBOUND_TUNNEL_LENGTH[] = "outbound.length"; const int DEFAULT_OUTBOUND_TUNNEL_LENGTH = 3; + const int STREAM_REQUEST_TIMEOUT = 60; //in seconds class ClientDestination: public i2p::garlic::GarlicDestination { @@ -64,6 +65,8 @@ namespace client // streaming i2p::stream::StreamingDestination * GetStreamingDestination () const { return m_StreamingDestination; }; + std::shared_ptr CreateStream (const std::string& dest, int port = 0); + std::shared_ptr CreateStream (const i2p::data::IdentHash& dest, int port = 0); std::shared_ptr CreateStream (const i2p::data::LeaseSet& remote, int port = 0); void AcceptStreams (const i2p::stream::StreamingDestination::Acceptor& acceptor); void StopAcceptingStreams ();