close I2P stream if socket got closed right after connect

This commit is contained in:
orignal
2026-03-06 13:50:16 -05:00
parent 08ea68a310
commit 0ed8b473f2
2 changed files with 49 additions and 36 deletions
+12 -7
View File
@@ -669,13 +669,18 @@ namespace proxy
{
if(stream)
{
m_ClientResponse.code = 200;
m_ClientResponse.status = "OK";
m_send_buf = m_ClientResponse.to_string();
m_sock->send(boost::asio::buffer(m_send_buf));
auto connection = std::make_shared<i2p::client::I2PTunnelConnection>(GetOwner(), m_sock, stream);
GetOwner()->AddHandler(connection);
connection->I2PConnect();
if (m_sock && m_sock->is_open ())
{
m_ClientResponse.code = 200;
m_ClientResponse.status = "OK";
m_send_buf = m_ClientResponse.to_string();
m_sock->send(boost::asio::buffer(m_send_buf));
auto connection = std::make_shared<i2p::client::I2PTunnelConnection>(GetOwner(), m_sock, stream);
GetOwner()->AddHandler(connection);
connection->I2PConnect();
}
else
stream->AsyncClose ();
m_sock = nullptr;
Terminate();
}
+37 -29
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2025, The PurpleI2P Project
* Copyright (c) 2013-2026, The PurpleI2P Project
*
* This file is part of Purple i2pd project and licensed under BSD3
*
@@ -90,7 +90,7 @@ namespace client
boost::asio::ip::address ourIP = boost::asio::ip::address_v6 (bytes);
return ourIP;
}
#ifdef __linux__
static void MapToLoopback(std::shared_ptr<boost::asio::ip::tcp::socket> sock, const i2p::data::IdentHash & addr, bool isV4)
{
@@ -116,7 +116,7 @@ namespace client
I2PTunnelSetSocketOptions (m_Socket);
#ifdef __linux__
if (isUniqueLocal && m_RemoteEndpoint.address ().is_loopback ())
{
{
auto ident = m_Stream->GetRemoteIdentity()->GetIdentHash();
if (m_RemoteEndpoint.address ().is_v4 ())
{
@@ -127,7 +127,7 @@ namespace client
{
m_Socket->open (boost::asio::ip::tcp::v6 ());
MapToLoopback(m_Socket, ident, false);
}
}
}
#endif
m_Socket->async_connect (m_RemoteEndpoint, std::bind (&I2PTunnelConnection::HandleConnect,
@@ -173,11 +173,11 @@ namespace client
size_t bufSize = I2P_TUNNEL_CONNECTION_BUFFER_SIZE;
size_t unsentSize = m_Stream ? m_Stream->GetSendBufferSize () : 0;
if (unsentSize)
{
{
if (unsentSize >= I2P_TUNNEL_CONNECTION_STREAM_MAX_SEND_BUFFER_SIZE) return; // buffer is full
if (unsentSize > I2P_TUNNEL_CONNECTION_STREAM_MAX_SEND_BUFFER_SIZE - I2P_TUNNEL_CONNECTION_BUFFER_SIZE)
bufSize = I2P_TUNNEL_CONNECTION_STREAM_MAX_SEND_BUFFER_SIZE - unsentSize;
}
}
m_IsReceiving = true;
if (m_SSL)
m_SSL->async_read_some (boost::asio::buffer(m_Buffer, bufSize),
@@ -201,7 +201,7 @@ namespace client
}
}
else
{
{
if (bytes_transferred < I2P_TUNNEL_CONNECTION_BUFFER_SIZE && !m_SSL)
{
boost::system::error_code ec;
@@ -212,22 +212,22 @@ namespace client
if (bytes_transferred + moreBytes > I2P_TUNNEL_CONNECTION_BUFFER_SIZE)
moreBytes = I2P_TUNNEL_CONNECTION_BUFFER_SIZE - bytes_transferred;
if (m_Stream->GetSendBufferSize () < I2P_TUNNEL_CONNECTION_STREAM_MAX_SEND_BUFFER_SIZE)
{
{
size_t remaining = I2P_TUNNEL_CONNECTION_STREAM_MAX_SEND_BUFFER_SIZE - m_Stream->GetSendBufferSize ();
if (remaining < moreBytes) moreBytes = remaining;
}
}
else
moreBytes = 0;
}
}
if (moreBytes)
{
moreBytes = boost::asio::read (*m_Socket, boost::asio::buffer(m_Buffer + bytes_transferred, moreBytes), boost::asio::transfer_all (), ec);
if (!ec) bytes_transferred += moreBytes;
}
}
}
}
WriteToStream (m_Buffer, bytes_transferred);
Receive (); // try to receive more while being sent to stream
}
}
}
void I2PTunnelConnection::WriteToStream (const uint8_t * buf, size_t len)
@@ -493,8 +493,8 @@ namespace client
// add X-I2P fields
m_OutHeader << m_XI2P;
// end of header
m_OutHeader << "\r\n";
m_OutHeader << "\r\n";
m_OutHeader << m_InHeader.str ().substr (m_InHeader.tellg ()); // data right after header
m_InHeader.str ("");
m_HeaderSent = true;
@@ -622,7 +622,7 @@ namespace client
uint16_t destinationPort, std::shared_ptr<boost::asio::ip::tcp::socket> socket):
I2PServiceHandler(parent), m_Address(address),
m_DestinationPort (destinationPort), m_Socket(socket) {};
void Handle();
void Handle() override;
void Terminate();
private:
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
@@ -643,11 +643,19 @@ namespace client
if (stream)
{
if (Kill()) return;
LogPrint (eLogDebug, "I2PTunnel: New connection");
auto connection = std::make_shared<I2PTunnelConnection>(GetOwner(), m_Socket, stream);
GetOwner()->AddHandler (connection);
connection->I2PConnect ();
Done(shared_from_this());
if (m_Socket && m_Socket->is_open ())
{
LogPrint (eLogDebug, "I2PTunnel: New connection");
auto connection = std::make_shared<I2PTunnelConnection>(GetOwner(), m_Socket, stream);
GetOwner()->AddHandler (connection);
connection->I2PConnect ();
Done(shared_from_this());
}
else
{
stream->AsyncClose ();
Terminate ();
}
}
else
{
@@ -770,9 +778,9 @@ namespace client
auto localDestination = GetLocalDestination ();
if (localDestination)
localDestination->StopAcceptingStreams ();
if (m_Resolver)
if (m_Resolver)
m_Resolver->cancel ();
ClearHandlers ();
}
@@ -784,8 +792,8 @@ namespace client
std::bind (&I2PServerTunnel::HandleResolve, this,
std::placeholders::_1, std::placeholders::_2, stream));
return true;
}
}
void I2PServerTunnel::HandleResolve (const boost::system::error_code& ecode, boost::asio::ip::tcp::resolver::results_type endpoints,
std::shared_ptr<i2p::stream::Stream> stream)
{
@@ -902,7 +910,7 @@ namespace client
LogPrint (eLogWarning, "I2PTunnel: Address ", m_Address, " can't be resolved. Incoming connection dropped");
stream->Close ();
return;
}
}
}
}
@@ -915,8 +923,8 @@ namespace client
conn->Connect (*m_LocalAddress);
else
conn->Connect (m_IsUniqueLocal);
}
}
std::shared_ptr<I2PTunnelConnection> I2PServerTunnel::CreateI2PConnection (std::shared_ptr<i2p::stream::Stream> stream)
{
return std::make_shared<I2PTunnelConnection> (this, stream, GetEndpoint (), m_SSLCtx);
@@ -942,7 +950,7 @@ namespace client
ss << X_I2P_DEST_HASH << ": " << from->GetIdentHash ().ToBase64 () << "\r\n";
ss << X_I2P_DEST_B64 << ": " << from->ToBase64 () << "\r\n";
m_XI2P = ss.str ();
}
}
return std::make_shared<I2PServerTunnelConnectionHTTP> (this, stream, GetEndpoint (), m_Host, m_XI2P, GetSSLCtx ());
}