diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 7accec1c..bb38f7f9 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -359,6 +359,24 @@ namespace client return true; } + std::shared_ptr AddressBook::GetAddress (const std::string& address) + { + auto pos = address.find(".b32.i2p"); + if (pos != std::string::npos) + return std::make_shared(address.substr (0, pos)); + else + { + pos = address.find (".i2p"); + if (pos != std::string::npos) + return FindAddress (address); + } + // if not .b32 we assume full base64 address + i2p::data::IdentityEx dest; + if (!dest.FromBase64 (address)) + return nullptr; + return std::make_shared(dest.GetIdentHash ()); + } + std::shared_ptr AddressBook::FindAddress (const std::string& address) { auto it = m_Addresses.find (address); diff --git a/libi2pd_client/AddressBook.h b/libi2pd_client/AddressBook.h index 51bf4b78..ed8e37ae 100644 --- a/libi2pd_client/AddressBook.h +++ b/libi2pd_client/AddressBook.h @@ -75,6 +75,7 @@ namespace client void StartResolvers (); void Stop (); bool GetIdentHash (const std::string& address, i2p::data::IdentHash& ident); + std::shared_ptr GetAddress (const std::string& address); std::shared_ptr GetFullAddress (const std::string& address); std::shared_ptr FindAddress (const std::string& address); void LookupAddress (const std::string& address); diff --git a/libi2pd_client/I2PService.cpp b/libi2pd_client/I2PService.cpp index 40df0161..7157020f 100644 --- a/libi2pd_client/I2PService.cpp +++ b/libi2pd_client/I2PService.cpp @@ -101,9 +101,9 @@ namespace client void I2PService::CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port) { assert(streamRequestComplete); - i2p::data::IdentHash identHash; - if (i2p::client::context.GetAddressBook ().GetIdentHash (dest, identHash)) - CreateStream(streamRequestComplete, identHash, port); + auto address = i2p::client::context.GetAddressBook ().GetAddress (dest); + if (address) + CreateStream(streamRequestComplete, address, port); else { LogPrint (eLogWarning, "I2PService: Remote destination not found: ", dest); @@ -111,27 +111,31 @@ namespace client } } - void I2PService::CreateStream(StreamRequestComplete streamRequestComplete, const i2p::data::IdentHash & identHash, int port) + void I2PService::CreateStream(StreamRequestComplete streamRequestComplete, std::shared_ptr address, int port) { - if(m_ConnectTimeout) + if(m_ConnectTimeout && !m_LocalDestination->IsReady()) { - if(m_LocalDestination->IsReady()) - m_LocalDestination->CreateStream (streamRequestComplete, identHash, port); - else - { - AddReadyCallback([this, streamRequestComplete, identHash, port] (const boost::system::error_code & ec) { - if(ec) - { - LogPrint(eLogWarning, "I2PService::CeateStream() ", ec.message()); - streamRequestComplete(nullptr); - } + AddReadyCallback([this, streamRequestComplete, address, port] (const boost::system::error_code & ec) { + if(ec) + { + LogPrint(eLogWarning, "I2PService::CeateStream() ", ec.message()); + streamRequestComplete(nullptr); + } + else + { if (address->IsIdentHash ()) + this->m_LocalDestination->CreateStream(streamRequestComplete, address->identHash, port); else - this->m_LocalDestination->CreateStream(streamRequestComplete, identHash, port); - }); - } + this->m_LocalDestination->CreateStream (streamRequestComplete, address->blindedPublicKey, port); + } + }); } else - m_LocalDestination->CreateStream(streamRequestComplete, identHash, port); + { + if (address->IsIdentHash ()) + m_LocalDestination->CreateStream (streamRequestComplete, address->identHash, port); + else + m_LocalDestination->CreateStream (streamRequestComplete, address->blindedPublicKey, port); + } } TCPIPPipe::TCPIPPipe(I2PService * owner, std::shared_ptr upstream, std::shared_ptr downstream) : I2PServiceHandler(owner), m_up(upstream), m_down(downstream) diff --git a/libi2pd_client/I2PService.h b/libi2pd_client/I2PService.h index 55921898..e0dfd2da 100644 --- a/libi2pd_client/I2PService.h +++ b/libi2pd_client/I2PService.h @@ -8,6 +8,7 @@ #include #include "Destination.h" #include "Identity.h" +#include "AddressBook.h" namespace i2p { @@ -49,7 +50,7 @@ namespace client m_LocalDestination = dest; } void CreateStream (StreamRequestComplete streamRequestComplete, const std::string& dest, int port = 0); - void CreateStream(StreamRequestComplete complete, const i2p::data::IdentHash & ident, int port); + void CreateStream(StreamRequestComplete complete, std::shared_ptr address, int port); inline boost::asio::io_service& GetService () { return m_LocalDestination->GetService (); } virtual void Start () = 0; diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 65600cf8..e45c7288 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -393,15 +393,15 @@ namespace client class I2PClientTunnelHandler: public I2PServiceHandler, public std::enable_shared_from_this { public: - I2PClientTunnelHandler (I2PClientTunnel * parent, i2p::data::IdentHash destination, + I2PClientTunnelHandler (I2PClientTunnel * parent, std::shared_ptr address, int destinationPort, std::shared_ptr socket): - I2PServiceHandler(parent), m_DestinationIdentHash(destination), + I2PServiceHandler(parent), m_Address(address), m_DestinationPort (destinationPort), m_Socket(socket) {}; void Handle(); void Terminate(); private: void HandleStreamRequestComplete (std::shared_ptr stream); - i2p::data::IdentHash m_DestinationIdentHash; + std::shared_ptr m_Address; int m_DestinationPort; std::shared_ptr m_Socket; }; @@ -410,7 +410,7 @@ namespace client { GetOwner()->CreateStream ( std::bind (&I2PClientTunnelHandler::HandleStreamRequestComplete, shared_from_this(), std::placeholders::_1), - m_DestinationIdentHash, m_DestinationPort); + m_Address, m_DestinationPort); } void I2PClientTunnelHandler::HandleStreamRequestComplete (std::shared_ptr stream) @@ -445,43 +445,39 @@ namespace client I2PClientTunnel::I2PClientTunnel (const std::string& name, const std::string& destination, const std::string& address, int port, std::shared_ptr localDestination, int destinationPort): TCPIPAcceptor (address, port, localDestination), m_Name (name), m_Destination (destination), - m_DestinationIdentHash (nullptr), m_DestinationPort (destinationPort) + m_DestinationPort (destinationPort) { } void I2PClientTunnel::Start () { TCPIPAcceptor::Start (); - GetIdentHash(); + GetAddress (); } void I2PClientTunnel::Stop () { TCPIPAcceptor::Stop(); - auto *originalIdentHash = m_DestinationIdentHash; - m_DestinationIdentHash = nullptr; - delete originalIdentHash; + m_Address = nullptr; } /* HACK: maybe we should create a caching IdentHash provider in AddressBook */ - const i2p::data::IdentHash * I2PClientTunnel::GetIdentHash () + std::shared_ptr I2PClientTunnel::GetAddress () { - if (!m_DestinationIdentHash) + if (!m_Address) { - i2p::data::IdentHash identHash; - if (i2p::client::context.GetAddressBook ().GetIdentHash (m_Destination, identHash)) - m_DestinationIdentHash = new i2p::data::IdentHash (identHash); - else + m_Address = i2p::client::context.GetAddressBook ().GetAddress (m_Destination); + if (!m_Address) LogPrint (eLogWarning, "I2PTunnel: Remote destination ", m_Destination, " not found"); } - return m_DestinationIdentHash; + return m_Address; } std::shared_ptr I2PClientTunnel::CreateHandler(std::shared_ptr socket) { - const i2p::data::IdentHash *identHash = GetIdentHash(); - if (identHash) - return std::make_shared(this, *identHash, m_DestinationPort, socket); + auto address = GetAddress (); + if (address) + return std::make_shared(this, address, m_DestinationPort, socket); else return nullptr; }