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 ():
 | 
						NTCP2Server::NTCP2Server ():
 | 
				
			||||||
		RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()),
 | 
							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):
 | 
												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);
 | 
													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.reset (new boost::asio::ip::tcp::acceptor (GetService (), ep));
 | 
				
			||||||
 | 
												m_NTCP2Acceptor->listen(this->m_listen_backlog);
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						catch ( std::exception & ex )
 | 
											catch ( std::exception & ex )
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
| 
						 | 
					@ -1261,7 +1263,7 @@ namespace transport
 | 
				
			||||||
							else if (m_YggdrasilAddress && !context.SupportsV6 ())
 | 
												else if (m_YggdrasilAddress && !context.SupportsV6 ())
 | 
				
			||||||
								ep = boost::asio::ip::tcp::endpoint (m_YggdrasilAddress->address(), address->port);
 | 
													ep = boost::asio::ip::tcp::endpoint (m_YggdrasilAddress->address(), address->port);
 | 
				
			||||||
							m_NTCP2V6Acceptor->bind (ep);
 | 
												m_NTCP2V6Acceptor->bind (ep);
 | 
				
			||||||
							m_NTCP2V6Acceptor->listen ();
 | 
												m_NTCP2V6Acceptor->listen(this->m_listen_backlog);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port);
 | 
												LogPrint (eLogInfo, "NTCP2: Start listening v6 TCP port ", address->port);
 | 
				
			||||||
							auto conn = std::make_shared<NTCP2Session> (*this);
 | 
												auto conn = std::make_shared<NTCP2Session> (*this);
 | 
				
			||||||
| 
						 | 
					@ -1325,6 +1327,7 @@ namespace transport
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (session && session->GetRemoteIdentity ())
 | 
							if (session && session->GetRemoteIdentity ())
 | 
				
			||||||
			m_NTCP2Sessions.erase (session->GetRemoteIdentity ()->GetIdentHash ());
 | 
								m_NTCP2Sessions.erase (session->GetRemoteIdentity ()->GetIdentHash ());
 | 
				
			||||||
 | 
							this->ResumeAcceptingIfOverloaded();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::shared_ptr<NTCP2Session> NTCP2Server::FindNTCP2Session (const i2p::data::IdentHash& ident)
 | 
						std::shared_ptr<NTCP2Session> NTCP2Server::FindNTCP2Session (const i2p::data::IdentHash& ident)
 | 
				
			||||||
| 
						 | 
					@ -1422,9 +1425,10 @@ namespace transport
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				LogPrint (eLogError, "NTCP2: Connected from error ", ec.message ());
 | 
									LogPrint (eLogError, "NTCP2: Connected from error ", ec.message ());
 | 
				
			||||||
		}
 | 
							} else  {
 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			LogPrint (eLogError, "NTCP2: Accept error ", error.message ());
 | 
								LogPrint (eLogError, "NTCP2: Accept error ", error.message ());
 | 
				
			||||||
 | 
								this->CheckIfOverloaded(conn, error, true);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (error != boost::asio::error::operation_aborted)
 | 
							if (error != boost::asio::error::operation_aborted)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -1455,11 +1459,54 @@ namespace transport
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				LogPrint (eLogError, "NTCP2: Connected from error ", ec.message ());
 | 
									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 (error != boost::asio::error::operation_aborted)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			conn = std::make_shared<NTCP2Session> (*this);
 | 
								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,
 | 
								m_NTCP2V6Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAcceptV6, this,
 | 
				
			||||||
				conn, std::placeholders::_1));
 | 
									conn, std::placeholders::_1));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -264,6 +264,9 @@ namespace transport
 | 
				
			||||||
			void HandleAccept (std::shared_ptr<NTCP2Session> conn, const boost::system::error_code& error);
 | 
								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 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 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 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);
 | 
								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::unique_ptr<boost::asio::ip::tcp::endpoint> m_ProxyEndpoint;
 | 
				
			||||||
			std::shared_ptr<boost::asio::ip::tcp::endpoint> m_Address4, m_Address6, m_YggdrasilAddress;
 | 
								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:
 | 
							public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// for HTTP/I2PControl
 | 
								// for HTTP/I2PControl
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue