mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	Setting up some response to file descriptor exhaustion
This commit is contained in:
		
							parent
							
								
									324932c758
								
							
						
					
					
						commit
						d399ce9a74
					
				
					 2 changed files with 60 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -1177,7 +1177,8 @@ namespace transport
 | 
			
		|||
 | 
			
		||||
	NTCP2Server::NTCP2Server ():
 | 
			
		||||
		RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()),
 | 
			
		||||
		 m_ProxyType(eNoProxy), m_Resolver(GetService ())
 | 
			
		||||
		 m_ProxyType(eNoProxy), m_Resolver(GetService ()),
 | 
			
		||||
		m_listen_backlog(boost::asio::socket_base::max_listen_connections)
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1223,6 +1224,7 @@ namespace transport
 | 
			
		|||
							auto ep = m_Address4 ? boost::asio::ip::tcp::endpoint (m_Address4->address(), address->port):
 | 
			
		||||
								boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4(), address->port);
 | 
			
		||||
							m_NTCP2Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService (), ep));
 | 
			
		||||
							m_NTCP2Acceptor->listen(this->m_listen_backlog);
 | 
			
		||||
						}
 | 
			
		||||
						catch ( std::exception & ex )
 | 
			
		||||
						{
 | 
			
		||||
| 
						 | 
				
			
			@ -1261,7 +1263,7 @@ namespace transport
 | 
			
		|||
							else if (m_YggdrasilAddress && !context.SupportsV6 ())
 | 
			
		||||
								ep = boost::asio::ip::tcp::endpoint (m_YggdrasilAddress->address(), address->port);
 | 
			
		||||
							m_NTCP2V6Acceptor->bind (ep);
 | 
			
		||||
							m_NTCP2V6Acceptor->listen ();
 | 
			
		||||
							m_NTCP2V6Acceptor->listen(this->m_listen_backlog);
 | 
			
		||||
 | 
			
		||||
							LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port);
 | 
			
		||||
							auto conn = std::make_shared<NTCP2Session> (*this);
 | 
			
		||||
| 
						 | 
				
			
			@ -1325,6 +1327,7 @@ namespace transport
 | 
			
		|||
	{
 | 
			
		||||
		if (session && session->GetRemoteIdentity ())
 | 
			
		||||
			m_NTCP2Sessions.erase (session->GetRemoteIdentity ()->GetIdentHash ());
 | 
			
		||||
		this->ResumeAcceptingIfOverloaded();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::shared_ptr<NTCP2Session> NTCP2Server::FindNTCP2Session (const i2p::data::IdentHash& ident)
 | 
			
		||||
| 
						 | 
				
			
			@ -1422,9 +1425,10 @@ namespace transport
 | 
			
		|||
			}
 | 
			
		||||
			else
 | 
			
		||||
				LogPrint (eLogError, "NTCP2: Connected from error ", ec.message ());
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		} else  {
 | 
			
		||||
			LogPrint (eLogError, "NTCP2: Accept error ", error.message ());
 | 
			
		||||
			this->CheckIfOverloaded(conn, error, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (error != boost::asio::error::operation_aborted)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -1455,11 +1459,54 @@ namespace transport
 | 
			
		|||
			}
 | 
			
		||||
			else
 | 
			
		||||
				LogPrint (eLogError, "NTCP2: Connected from error ", ec.message ());
 | 
			
		||||
		} else {
 | 
			
		||||
			LogPrint (eLogError, "NTCP2: Accept error ", error.message ());
 | 
			
		||||
			this->CheckIfOverloaded(conn, error, false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (error != boost::asio::error::operation_aborted)
 | 
			
		||||
		{
 | 
			
		||||
			if (!conn) // connection is used, create new one
 | 
			
		||||
				conn = std::make_shared<NTCP2Session> (*this);
 | 
			
		||||
			else // reuse failed
 | 
			
		||||
				conn->Close ();
 | 
			
		||||
			m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this,
 | 
			
		||||
				conn, std::placeholders::_1));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void NTCP2Server::CheckIfOverloaded (std::shared_ptr<NTCP2Session> conn, const boost::system::error_code& error, bool isv4)
 | 
			
		||||
	{
 | 
			
		||||
		// TODO: high water / low water sophistry
 | 
			
		||||
		if(error == boost::system::errc::too_many_files_open_in_system ||
 | 
			
		||||
		   error == boost::system::errc::too_many_files_open) {
 | 
			
		||||
			// I have to wait until a file closes to accept more.
 | 
			
		||||
			conn->Close();
 | 
			
		||||
			this->m_overloaded = true;
 | 
			
		||||
			this->m_listen_backlog = (this->m_listen_backlog + 128) >> 1;
 | 
			
		||||
			m_NTCP2Acceptor->listen(this->m_listen_backlog);
 | 
			
		||||
			m_NTCP2V6Acceptor->listen(this->m_listen_backlog);
 | 
			
		||||
		}
 | 
			
		||||
		if(this->m_overloaded) {
 | 
			
		||||
			if(isv4) {
 | 
			
		||||
				this->need_resume_v4 = true;
 | 
			
		||||
			} else {
 | 
			
		||||
				this->need_resume_v6 = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void NTCP2Server::ResumeAcceptingIfOverloaded ()
 | 
			
		||||
	{
 | 
			
		||||
		if(!this->m_overloaded) return;
 | 
			
		||||
		std::shared_ptr<NTCP2Session> conn = std::make_shared<NTCP2Session>(*this);
 | 
			
		||||
		if(this->need_resume_v4) {
 | 
			
		||||
			this->need_resume_v4 = false;
 | 
			
		||||
			m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this,
 | 
			
		||||
				conn, std::placeholders::_1));
 | 
			
		||||
		}
 | 
			
		||||
		if(this->need_resume_v6) {
 | 
			
		||||
			this->need_resume_v6 = false;
 | 
			
		||||
			m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this,
 | 
			
		||||
				conn, std::placeholders::_1));
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -264,6 +264,9 @@ namespace transport
 | 
			
		|||
			void HandleAccept (std::shared_ptr<NTCP2Session> conn, const boost::system::error_code& error);
 | 
			
		||||
			void HandleAcceptV6 (std::shared_ptr<NTCP2Session> conn, const boost::system::error_code& error);
 | 
			
		||||
 | 
			
		||||
			void CheckIfOverloaded (std::shared_ptr<NTCP2Session> conn, const boost::system::error_code& error, bool isv4);
 | 
			
		||||
			void ResumeAcceptingIfOverloaded();
 | 
			
		||||
 | 
			
		||||
			void HandleConnect (const boost::system::error_code& ecode, std::shared_ptr<NTCP2Session> conn, std::shared_ptr<boost::asio::deadline_timer> timer);
 | 
			
		||||
			void HandleProxyConnect(const boost::system::error_code& ecode, std::shared_ptr<NTCP2Session> conn, std::shared_ptr<boost::asio::deadline_timer> timer);
 | 
			
		||||
			void AfterSocksHandshake(std::shared_ptr<NTCP2Session> conn, std::shared_ptr<boost::asio::deadline_timer> timer);
 | 
			
		||||
| 
						 | 
				
			
			@ -286,6 +289,11 @@ namespace transport
 | 
			
		|||
			std::unique_ptr<boost::asio::ip::tcp::endpoint> m_ProxyEndpoint;
 | 
			
		||||
			std::shared_ptr<boost::asio::ip::tcp::endpoint> m_Address4, m_Address6, m_YggdrasilAddress;
 | 
			
		||||
 | 
			
		||||
			bool m_overloaded;
 | 
			
		||||
			bool need_resume_v4;
 | 
			
		||||
			bool need_resume_v6;
 | 
			
		||||
			int m_listen_backlog;
 | 
			
		||||
 | 
			
		||||
		public:
 | 
			
		||||
 | 
			
		||||
			// for HTTP/I2PControl
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue