From 475f40f8d925afc7519ffdfa59144a62b2a39017 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 17 Oct 2026 21:55:50 -0400 Subject: [PATCH] use stringstream::view instead stringstream::str for server tunnel. Count headers for entire connection --- libi2pd_client/I2PTunnel.cpp | 33 +++++++++++++++++++++++++-------- libi2pd_client/I2PTunnel.h | 6 ++++-- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 4a9a788a..42bc9c2c 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -392,14 +392,19 @@ namespace client m_InHeader.clear (); m_InHeader.write ((const char *)buf, len); std::string line; - int numHeaders = 0; bool endOfHeader = false; - while (!endOfHeader && numHeaders < I2P_TUNNL_MAX_NUM_HTTP_HEADERS) + while (!endOfHeader) { std::getline(m_InHeader, line); if (!m_InHeader.fail () && !m_InHeader.eof ()) { - numHeaders++; + m_NumHeaders++; + if (m_NumHeaders > I2P_TUNNEL_MAX_NUM_HTTP_HEADERS) + { + LogPrint (eLogError, "I2PTunnel: HTTP headers number exceeds max ", I2P_TUNNEL_MAX_NUM_HTTP_HEADERS); + Terminate (); + return; + } if (line == "\r") endOfHeader = true; else { @@ -453,7 +458,6 @@ namespace client else { LogPrint (eLogError, "I2PTunnel: HTTP header exceeds max size ", I2P_TUNNEL_HTTP_MAX_HEADER_SIZE); - m_InHeader.str (""); m_OutHeader.str (""); Terminate (); } } @@ -463,7 +467,7 @@ namespace client const boost::asio::ip::tcp::endpoint& target, const std::string& host, const std::string& XI2P, std::shared_ptr sslCtx): I2PTunnelConnection (owner, stream, target, sslCtx), m_Host (host), m_XI2P (XI2P), - m_HeaderSent (false), m_ResponseHeaderSent (false) + m_HeaderSent (false), m_ResponseHeaderSent (false), m_NumHeaders (0) { if (sslCtx) SSL_set_tlsext_host_name(GetSSL ()->native_handle(), host.c_str ()); @@ -488,6 +492,13 @@ namespace client if (line == "\r") endOfHeader = true; else { + m_NumHeaders++; + if (m_NumHeaders > I2P_TUNNEL_MAX_NUM_HTTP_HEADERS) + { + LogPrint (eLogError, "I2PTunnel: HTTP headers number exceeds max ", I2P_TUNNEL_MAX_NUM_HTTP_HEADERS); + Terminate (); + return; + } // strip up some headers static constexpr std::array excluded // list of excluded headers { @@ -520,6 +531,12 @@ namespace client } else { + if (line.length () > I2P_TUNNEL_HTTP_MAX_HEADER_SIZE) + { + LogPrint (eLogError, "I2PTunnel: HTTP header line exceeds max size ", I2P_TUNNEL_HTTP_MAX_HEADER_SIZE); + Terminate (); + return; + } // insert incomplete line back m_InHeader.clear (); m_InHeader << line; @@ -537,12 +554,12 @@ namespace client // end of header m_OutHeader << "\r\n"; - m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header + m_OutHeader << m_InHeader.view ().substr (m_InHeader.tellg ()); // data right after header m_InHeader.str (""); m_HeaderSent = true; - I2PTunnelConnection::Write ((uint8_t *)m_OutHeader.str ().c_str (), m_OutHeader.str ().length ()); + I2PTunnelConnection::Write ((const uint8_t *)m_OutHeader.view ().data (), m_OutHeader.view ().size ()); } - else if (m_OutHeader.tellp () < I2P_TUNNEL_HTTP_MAX_HEADER_SIZE) + else if (m_OutHeader.view ().size () < I2P_TUNNEL_HTTP_MAX_HEADER_SIZE && m_InHeader.view ().size () < I2P_TUNNEL_HTTP_MAX_HEADER_SIZE) StreamReceive (); // read more header else { diff --git a/libi2pd_client/I2PTunnel.h b/libi2pd_client/I2PTunnel.h index 4e1d813d..451954bf 100644 --- a/libi2pd_client/I2PTunnel.h +++ b/libi2pd_client/I2PTunnel.h @@ -39,7 +39,7 @@ namespace client constexpr std::string_view X_I2P_DEST_B64 { "X-I2P-DestB64" }; // full address in base64 constexpr std::string_view X_I2P_DEST_B32 { "X-I2P-DestB32" }; // .b32.i2p address constexpr int I2P_TUNNEL_HTTP_MAX_HEADER_SIZE = 8192; - constexpr int I2P_TUNNL_MAX_NUM_HTTP_HEADERS = 100; + constexpr int I2P_TUNNEL_MAX_NUM_HTTP_HEADERS = 100; class I2PTunnelConnection: public I2PServiceHandler, public std::enable_shared_from_this { @@ -97,7 +97,7 @@ namespace client I2PClientTunnelConnectionHTTP (std::shared_ptr owner, std::shared_ptr socket, std::shared_ptr stream): I2PTunnelConnection (owner, socket, stream), m_HeaderSent (false), - m_ConnectionSent (false), m_ProxyConnectionSent (false) {}; + m_ConnectionSent (false), m_ProxyConnectionSent (false), m_NumHeaders (0) {}; protected: @@ -107,6 +107,7 @@ namespace client std::stringstream m_InHeader, m_OutHeader; bool m_HeaderSent, m_ConnectionSent, m_ProxyConnectionSent; + int m_NumHeaders; }; class I2PServerTunnelConnectionHTTP: public I2PTunnelConnection @@ -127,6 +128,7 @@ namespace client std::string m_Host, m_XI2P; std::stringstream m_InHeader, m_OutHeader; bool m_HeaderSent, m_ResponseHeaderSent; + int m_NumHeaders; }; class I2PTunnelConnectionIRC: public I2PTunnelConnection