From 648b09d45f3283c3524e6f0918c713fd48edf387 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 10 Dec 2022 15:44:37 -0500 Subject: [PATCH] try to restart acceptors after termination of expired NTCP2 if no descriptors --- libi2pd/NTCP2.cpp | 67 +++++++++++++++++++++++++++-------------------- libi2pd/NTCP2.h | 4 --- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 555a5622..f78999be 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1424,20 +1424,18 @@ namespace transport else LogPrint (eLogError, "NTCP2: Connected from error ", ec.message ()); } - else if (error == boost::asio::error::no_descriptors) - { - i2p::context.SetError (eRouterErrorNoDescriptors); - if (m_NoFileExhaustTimestamp < i2p::util::GetSecondsSinceEpoch () - NTCP2_DESCRIPTORS_EXHAUST_TIMEOUT) - { - m_NoFileExhaustTimestamp = i2p::util::GetSecondsSinceEpoch (); - LogPrint (eLogWarning, "NTCP2: WARNING! i2pd met file descriptors exhaustion! Please check your nofile limits!"); - } - } else + { LogPrint (eLogError, "NTCP2: Accept error ", error.message ()); - + if (error == boost::asio::error::no_descriptors) + { + i2p::context.SetError (eRouterErrorNoDescriptors); + return; + } + } + if (error != boost::asio::error::operation_aborted) - { + { if (!conn) // connection is used, create new one conn = std::make_shared (*this); else // reuse failed @@ -1464,26 +1462,21 @@ namespace transport } } else - LogPrint (eLogError, "NTCP2: Connected from ipv6 error: ", ec.message ()); - } - else if (error == boost::asio::error::no_descriptors) - { - i2p::context.SetErrorV6 (eRouterErrorNoDescriptors); - if (m_NoFileExhaustTimestamp < i2p::util::GetSecondsSinceEpoch () - NTCP2_DESCRIPTORS_EXHAUST_TIMEOUT) - { - m_NoFileExhaustTimestamp = i2p::util::GetSecondsSinceEpoch (); - LogPrint (eLogWarning, "NTCP2: WARNING! i2pd met file descriptors exhaustion! Please check your nofile limits!"); - } + LogPrint (eLogError, "NTCP2: Connected from error ", ec.message ()); } else - LogPrint (eLogError, "NTCP2: Accept ipv6 error: ", error.message ()); + { + LogPrint (eLogError, "NTCP2: Accept ipv6 error ", error.message ()); + if (error == boost::asio::error::no_descriptors) + { + i2p::context.SetErrorV6 (eRouterErrorNoDescriptors); + return; + } + } if (error != boost::asio::error::operation_aborted) { - if (!conn) // connection is used, create new one - conn = std::make_shared (*this); - else // reuse failed - conn->Close (); + conn = std::make_shared (*this); m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, conn, std::placeholders::_1)); } @@ -1524,8 +1517,24 @@ namespace transport else it++; } - ScheduleTermination (); + + // try to restart acceptors if no description + // we do it after timer to let timer take descriptor first + if (i2p::context.GetError () == eRouterErrorNoDescriptors) + { + i2p::context.SetError (eRouterErrorNone); + auto conn = std::make_shared (*this); + m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, + conn, std::placeholders::_1)); + } + if (i2p::context.GetErrorV6 () == eRouterErrorNoDescriptors) + { + i2p::context.SetErrorV6 (eRouterErrorNone); + auto conn = std::make_shared (*this); + m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this, + conn, std::placeholders::_1)); + } } } @@ -1733,7 +1742,7 @@ namespace transport }); boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff->data (), SOCKS5_UDP_IPV4_REQUEST_HEADER_SIZE), // read min reply size - boost::asio::transfer_all(), + boost::asio::transfer_all(), [timer, conn, sz, readbuff](const boost::system::error_code & e, std::size_t transferred) { if (e) @@ -1741,7 +1750,7 @@ namespace transport else if (!(*readbuff)[1]) // succeeded { boost::system::error_code ec; - size_t moreBytes = conn->GetSocket ().available(ec); + size_t moreBytes = conn->GetSocket ().available(ec); if (moreBytes) // read remaining portion of reply if ipv6 received boost::asio::read (conn->GetSocket (), boost::asio::buffer(readbuff->data (), moreBytes), boost::asio::transfer_all (), ec); timer->cancel(); diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index c8c86e5d..754f5a6d 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -43,8 +43,6 @@ namespace transport const int NTCP2_CLOCK_SKEW = 60; // in seconds const int NTCP2_MAX_OUTGOING_QUEUE_SIZE = 500; // how many messages we can queue up - const int NTCP2_DESCRIPTORS_EXHAUST_TIMEOUT = 60; // 1 minute - enum NTCP2BlockType { eNTCP2BlkDateTime = 0, @@ -288,8 +286,6 @@ namespace transport std::unique_ptr m_ProxyEndpoint; std::shared_ptr m_Address4, m_Address6, m_YggdrasilAddress; - uint64_t m_NoFileExhaustTimestamp; - public: // for HTTP/I2PControl