diff --git a/libi2pd_client/BOB.cpp b/libi2pd_client/BOB.cpp index f2dab223..8d94e94b 100644 --- a/libi2pd_client/BOB.cpp +++ b/libi2pd_client/BOB.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2024, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -16,6 +16,24 @@ namespace i2p { namespace client { + void BOBI2PTunnelIncomingConnection::Established () + { + if (m_IsQuiet) + StreamReceive (); + else + { + // send destination first like received from I2P + std::string dest = GetStream ()->GetRemoteIdentity ()->ToBase64 (); + dest += "\n"; + if (dest.size() <= I2P_TUNNEL_CONNECTION_BUFFER_SIZE) + memcpy (GetStreamBuffer (), dest.c_str (), dest.size ()); + else + memset (GetStreamBuffer (), 0, I2P_TUNNEL_CONNECTION_BUFFER_SIZE); + HandleStreamReceive (boost::system::error_code (), dest.size ()); + } + Receive (); + } + BOBI2PInboundTunnel::BOBI2PInboundTunnel (const boost::asio::ip::tcp::endpoint& ep, std::shared_ptr localDestination): BOBI2PTunnel (localDestination), m_Acceptor (localDestination->GetService (), ep) { @@ -156,7 +174,7 @@ namespace client { if (stream) { - auto conn = std::make_shared (this, stream, m_Endpoint, m_IsQuiet); + auto conn = std::make_shared (this, stream, m_Endpoint, m_IsQuiet); AddHandler (conn); conn->Connect (); } diff --git a/libi2pd_client/BOB.h b/libi2pd_client/BOB.h index 79066154..f5aefd0a 100644 --- a/libi2pd_client/BOB.h +++ b/libi2pd_client/BOB.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2024, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -71,6 +71,23 @@ namespace client const char BOB_HELP_STATUS[] = "status - Display status of a nicknamed tunnel."; const char BOB_HELP_HELP [] = "help - Get help on a command."; + class BOBI2PTunnelIncomingConnection: public I2PTunnelConnection + { + public: + + BOBI2PTunnelIncomingConnection (I2PService * owner, std::shared_ptr stream, + const boost::asio::ip::tcp::endpoint& target, bool quiet): + I2PTunnelConnection (owner, stream, target), m_IsQuiet (quiet) {}; + + protected: + + void Established () override; + + private: + + bool m_IsQuiet; // don't send destination + }; + class BOBI2PTunnel: public I2PService { public: diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 3a3c491e..6d45c10c 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2024, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -32,8 +32,7 @@ namespace client I2PTunnelConnection::I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, std::shared_ptr leaseSet, uint16_t port): - I2PServiceHandler(owner), m_Socket (socket), m_RemoteEndpoint (socket->remote_endpoint ()), - m_IsQuiet (true) + I2PServiceHandler(owner), m_Socket (socket), m_RemoteEndpoint (socket->remote_endpoint ()) { m_Stream = GetOwner()->GetLocalDestination ()->CreateStream (leaseSet, port); } @@ -41,14 +40,13 @@ namespace client I2PTunnelConnection::I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, std::shared_ptr stream): I2PServiceHandler(owner), m_Socket (socket), m_Stream (stream), - m_RemoteEndpoint (socket->remote_endpoint ()), m_IsQuiet (true) + m_RemoteEndpoint (socket->remote_endpoint ()) { } I2PTunnelConnection::I2PTunnelConnection (I2PService * owner, std::shared_ptr stream, - const boost::asio::ip::tcp::endpoint& target, bool quiet, - std::shared_ptr sslCtx): - I2PServiceHandler(owner), m_Stream (stream), m_RemoteEndpoint (target), m_IsQuiet (quiet) + const boost::asio::ip::tcp::endpoint& target,std::shared_ptr sslCtx): + I2PServiceHandler(owner), m_Stream (stream), m_RemoteEndpoint (target) { m_Socket = std::make_shared (owner->GetService ()); if (sslCtx) @@ -292,18 +290,7 @@ namespace client void I2PTunnelConnection::Established () { - if (m_IsQuiet) - StreamReceive (); - else - { - // send destination first like received from I2P - std::string dest = m_Stream->GetRemoteIdentity ()->ToBase64 (); - dest += "\n"; - if(sizeof(m_StreamBuffer) >= dest.size()) { - memcpy (m_StreamBuffer, dest.c_str (), dest.size ()); - } - HandleStreamReceive (boost::system::error_code (), dest.size ()); - } + StreamReceive (); Receive (); } @@ -377,7 +364,7 @@ namespace client I2PServerTunnelConnectionHTTP::I2PServerTunnelConnectionHTTP (I2PService * owner, std::shared_ptr stream, const boost::asio::ip::tcp::endpoint& target, const std::string& host, const std::string& XI2P, std::shared_ptr sslCtx): - I2PTunnelConnection (owner, stream, target, true, sslCtx), m_Host (host), m_XI2P (XI2P), + I2PTunnelConnection (owner, stream, target, sslCtx), m_Host (host), m_XI2P (XI2P), m_HeaderSent (false), m_ResponseHeaderSent (false) { if (sslCtx) @@ -528,7 +515,7 @@ namespace client I2PTunnelConnectionIRC::I2PTunnelConnectionIRC (I2PService * owner, std::shared_ptr stream, const boost::asio::ip::tcp::endpoint& target, const std::string& webircpass, std::shared_ptr sslCtx): - I2PTunnelConnection (owner, stream, target, true, sslCtx), m_From (stream->GetRemoteIdentity ()), + I2PTunnelConnection (owner, stream, target, sslCtx), m_From (stream->GetRemoteIdentity ()), m_NeedsWebIrc (webircpass.length() ? true : false), m_WebircPass (webircpass) { } @@ -857,7 +844,7 @@ namespace client std::shared_ptr I2PServerTunnel::CreateI2PConnection (std::shared_ptr stream) { - return std::make_shared (this, stream, GetEndpoint (), true, m_SSLCtx); + return std::make_shared (this, stream, GetEndpoint (), m_SSLCtx); } diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 72602007..7d4c3400 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -45,7 +45,7 @@ namespace client I2PTunnelConnection (I2PService * owner, std::shared_ptr socket, std::shared_ptr stream); // to I2P using simplified API I2PTunnelConnection (I2PService * owner, std::shared_ptr stream, - const boost::asio::ip::tcp::endpoint& target, bool quiet = true, + const boost::asio::ip::tcp::endpoint& target, std::shared_ptr sslCtx = nullptr); // from I2P ~I2PTunnelConnection (); void I2PConnect (const uint8_t * msg = nullptr, size_t len = 0); @@ -54,25 +54,27 @@ namespace client protected: + virtual void Established (); void Terminate (); void Receive (); void StreamReceive (); + void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); virtual void Write (const uint8_t * buf, size_t len); // can be overloaded virtual void WriteToStream (const uint8_t * buf, size_t len); // can be overloaded std::shared_ptr GetSocket () const { return m_Socket; }; + std::shared_ptr GetStream () const { return m_Stream; }; std::shared_ptr > GetSSL () const { return m_SSL; }; - + uint8_t * GetStreamBuffer () { return m_StreamBuffer; }; + private: void HandleConnect (const boost::system::error_code& ecode); void HandleHandshake (const boost::system::error_code& ecode); - void Established (); void HandleReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); void HandleWrite (const boost::system::error_code& ecode); - void HandleStreamReceive (const boost::system::error_code& ecode, std::size_t bytes_transferred); - + private: uint8_t m_Buffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE], m_StreamBuffer[I2P_TUNNEL_CONNECTION_BUFFER_SIZE]; @@ -80,7 +82,6 @@ namespace client std::shared_ptr > m_SSL; std::shared_ptr m_Stream; boost::asio::ip::tcp::endpoint m_RemoteEndpoint; - bool m_IsQuiet; // don't send destination }; class I2PClientTunnelConnectionHTTP: public I2PTunnelConnection @@ -94,7 +95,7 @@ namespace client protected: - void Write (const uint8_t * buf, size_t len); + void Write (const uint8_t * buf, size_t len) override; private: @@ -112,8 +113,8 @@ namespace client protected: - void Write (const uint8_t * buf, size_t len); - void WriteToStream (const uint8_t * buf, size_t len); + void Write (const uint8_t * buf, size_t len) override; + void WriteToStream (const uint8_t * buf, size_t len) override; private: @@ -132,7 +133,7 @@ namespace client protected: - void Write (const uint8_t * buf, size_t len); + void Write (const uint8_t * buf, size_t len) override; private: