mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 08:00:38 +03:00
initial ntcp soft/hard limits
This commit is contained in:
parent
bc11181d5e
commit
6441c9d5d8
@ -71,6 +71,8 @@ namespace config {
|
|||||||
("limits.coresize", value<uint32_t>()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)")
|
("limits.coresize", value<uint32_t>()->default_value(0), "Maximum size of corefile in Kb (0 - use system limit)")
|
||||||
("limits.openfiles", value<uint16_t>()->default_value(0), "Maximum number of open files (0 - use system default)")
|
("limits.openfiles", value<uint16_t>()->default_value(0), "Maximum number of open files (0 - use system default)")
|
||||||
("limits.transittunnels", value<uint16_t>()->default_value(2500), "Maximum active transit sessions (default:2500)")
|
("limits.transittunnels", value<uint16_t>()->default_value(2500), "Maximum active transit sessions (default:2500)")
|
||||||
|
("limits.ntcpsoft", value<uint16_t>()->default_value(0), "Threshold to start probabalistic backoff with ntcp sessions (default: use system limit)")
|
||||||
|
("limits.ntcphard", value<uint16_t>()->default_value(0), "Maximum number of ntcp sessions (default: use system limit)")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description httpserver("HTTP Server options");
|
options_description httpserver("HTTP Server options");
|
||||||
|
@ -791,7 +791,8 @@ namespace transport
|
|||||||
NTCPServer::NTCPServer ():
|
NTCPServer::NTCPServer ():
|
||||||
m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service),
|
m_IsRunning (false), m_Thread (nullptr), m_Work (m_Service),
|
||||||
m_TerminationTimer (m_Service), m_NTCPAcceptor (nullptr), m_NTCPV6Acceptor (nullptr),
|
m_TerminationTimer (m_Service), m_NTCPAcceptor (nullptr), m_NTCPV6Acceptor (nullptr),
|
||||||
m_ProxyType(eNoProxy), m_Resolver(m_Service), m_ProxyEndpoint(nullptr)
|
m_ProxyType(eNoProxy), m_Resolver(m_Service), m_ProxyEndpoint(nullptr),
|
||||||
|
m_SoftLimit(0), m_HardLimit(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,6 +966,13 @@ namespace transport
|
|||||||
auto ep = conn->GetSocket ().remote_endpoint(ec);
|
auto ep = conn->GetSocket ().remote_endpoint(ec);
|
||||||
if (!ec)
|
if (!ec)
|
||||||
{
|
{
|
||||||
|
if(ShouldLimit())
|
||||||
|
{
|
||||||
|
// hit limit, close premature
|
||||||
|
LogPrint(eLogWarning, "NTCP: limiting with backoff session from ", ep);
|
||||||
|
conn->GetSocket().close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
LogPrint (eLogDebug, "NTCP: Connected from ", ep);
|
LogPrint (eLogDebug, "NTCP: Connected from ", ep);
|
||||||
if (conn)
|
if (conn)
|
||||||
{
|
{
|
||||||
@ -993,6 +1001,14 @@ namespace transport
|
|||||||
auto ep = conn->GetSocket ().remote_endpoint(ec);
|
auto ep = conn->GetSocket ().remote_endpoint(ec);
|
||||||
if (!ec)
|
if (!ec)
|
||||||
{
|
{
|
||||||
|
if(ShouldLimit())
|
||||||
|
{
|
||||||
|
// hit limit, close premature
|
||||||
|
LogPrint(eLogWarning, "NTCP: limiting with backoff on session from ", ep);
|
||||||
|
conn->GetSocket().close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LogPrint (eLogDebug, "NTCP: Connected from ", ep);
|
LogPrint (eLogDebug, "NTCP: Connected from ", ep);
|
||||||
if (conn)
|
if (conn)
|
||||||
{
|
{
|
||||||
|
@ -167,8 +167,19 @@ namespace transport
|
|||||||
|
|
||||||
boost::asio::io_service& GetService () { return m_Service; };
|
boost::asio::io_service& GetService () { return m_Service; };
|
||||||
|
|
||||||
|
void SetSessionLimits(uint16_t softLimit, uint16_t hardLimit) { m_SoftLimit = softLimit; m_HardLimit = hardLimit; }
|
||||||
|
bool ShouldLimit() const { return ShouldHardLimit() || ShouldSoftLimit(); }
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/** @brief return true for hard limit */
|
||||||
|
bool ShouldHardLimit() const { return m_HardLimit && m_NTCPSessions.size() >= m_HardLimit; }
|
||||||
|
|
||||||
|
/** @brief return true for probabalistic soft backoff */
|
||||||
|
bool ShouldSoftLimit() const
|
||||||
|
{
|
||||||
|
auto sessions = m_NTCPSessions.size();
|
||||||
|
return sessions && m_SoftLimit && m_SoftLimit < sessions && ( rand() % sessions ) <= m_SoftLimit;
|
||||||
|
}
|
||||||
void Run ();
|
void Run ();
|
||||||
void HandleAccept (std::shared_ptr<NTCPSession> conn, const boost::system::error_code& error);
|
void HandleAccept (std::shared_ptr<NTCPSession> conn, const boost::system::error_code& error);
|
||||||
void HandleAcceptV6 (std::shared_ptr<NTCPSession> conn, const boost::system::error_code& error);
|
void HandleAcceptV6 (std::shared_ptr<NTCPSession> conn, const boost::system::error_code& error);
|
||||||
@ -198,6 +209,8 @@ namespace transport
|
|||||||
uint16_t m_ProxyPort;
|
uint16_t m_ProxyPort;
|
||||||
boost::asio::ip::tcp::resolver m_Resolver;
|
boost::asio::ip::tcp::resolver m_Resolver;
|
||||||
boost::asio::ip::tcp::endpoint * m_ProxyEndpoint;
|
boost::asio::ip::tcp::endpoint * m_ProxyEndpoint;
|
||||||
|
|
||||||
|
uint16_t m_SoftLimit, m_HardLimit;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// for HTTP/I2PControl
|
// for HTTP/I2PControl
|
||||||
|
@ -147,13 +147,20 @@ namespace transport
|
|||||||
m_PeerTestTimer = new boost::asio::deadline_timer (*m_Service);
|
m_PeerTestTimer = new boost::asio::deadline_timer (*m_Service);
|
||||||
}
|
}
|
||||||
|
|
||||||
i2p::config::GetOption("nat", m_IsNAT);
|
i2p::config::GetOption("nat", m_IsNAT);
|
||||||
|
|
||||||
m_DHKeysPairSupplier.Start ();
|
m_DHKeysPairSupplier.Start ();
|
||||||
m_IsRunning = true;
|
m_IsRunning = true;
|
||||||
m_Thread = new std::thread (std::bind (&Transports::Run, this));
|
m_Thread = new std::thread (std::bind (&Transports::Run, this));
|
||||||
std::string ntcpproxy; i2p::config::GetOption("ntcpproxy", ntcpproxy);
|
std::string ntcpproxy; i2p::config::GetOption("ntcpproxy", ntcpproxy);
|
||||||
i2p::http::URL proxyurl;
|
i2p::http::URL proxyurl;
|
||||||
|
uint16_t softLimit, hardLimit;
|
||||||
|
i2p::config::GetOption("limits.ntcpsoft", softLimit);
|
||||||
|
i2p::config::GetOption("limits.ntcphard", hardLimit);
|
||||||
|
if(softLimit >= hardLimit)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "ntcp soft limit must be less than ntcp hard limit");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(ntcpproxy.size() && enableNTCP)
|
if(ntcpproxy.size() && enableNTCP)
|
||||||
{
|
{
|
||||||
if(proxyurl.parse(ntcpproxy))
|
if(proxyurl.parse(ntcpproxy))
|
||||||
@ -161,12 +168,11 @@ namespace transport
|
|||||||
if(proxyurl.schema == "socks" || proxyurl.schema == "http")
|
if(proxyurl.schema == "socks" || proxyurl.schema == "http")
|
||||||
{
|
{
|
||||||
m_NTCPServer = new NTCPServer();
|
m_NTCPServer = new NTCPServer();
|
||||||
|
m_NTCPServer->SetSessionLimits(softLimit, hardLimit);
|
||||||
NTCPServer::ProxyType proxytype = NTCPServer::eSocksProxy;
|
NTCPServer::ProxyType proxytype = NTCPServer::eSocksProxy;
|
||||||
|
|
||||||
if (proxyurl.schema == "http")
|
if (proxyurl.schema == "http")
|
||||||
proxytype = NTCPServer::eHTTPProxy;
|
proxytype = NTCPServer::eHTTPProxy;
|
||||||
|
|
||||||
m_NTCPServer->UseProxy(proxytype, proxyurl.host, proxyurl.port) ;
|
m_NTCPServer->UseProxy(proxytype, proxyurl.host, proxyurl.port) ;
|
||||||
m_NTCPServer->Start();
|
m_NTCPServer->Start();
|
||||||
if(!m_NTCPServer->NetworkIsReady())
|
if(!m_NTCPServer->NetworkIsReady())
|
||||||
@ -193,6 +199,7 @@ namespace transport
|
|||||||
if (m_NTCPServer == nullptr && enableNTCP)
|
if (m_NTCPServer == nullptr && enableNTCP)
|
||||||
{
|
{
|
||||||
m_NTCPServer = new NTCPServer ();
|
m_NTCPServer = new NTCPServer ();
|
||||||
|
m_NTCPServer->SetSessionLimits(softLimit, hardLimit);
|
||||||
m_NTCPServer->Start ();
|
m_NTCPServer->Start ();
|
||||||
if (!(m_NTCPServer->IsBoundV6() || m_NTCPServer->IsBoundV4())) {
|
if (!(m_NTCPServer->IsBoundV6() || m_NTCPServer->IsBoundV4())) {
|
||||||
/** failed to bind to NTCP */
|
/** failed to bind to NTCP */
|
||||||
@ -394,20 +401,27 @@ namespace transport
|
|||||||
{
|
{
|
||||||
if (!peer.router->UsesIntroducer () && !peer.router->IsUnreachable ())
|
if (!peer.router->UsesIntroducer () && !peer.router->IsUnreachable ())
|
||||||
{
|
{
|
||||||
auto s = std::make_shared<NTCPSession> (*m_NTCPServer, peer.router);
|
if(!m_NTCPServer->ShouldLimit())
|
||||||
if(m_NTCPServer->UsingProxy())
|
|
||||||
{
|
{
|
||||||
NTCPServer::RemoteAddressType remote = NTCPServer::eIP4Address;
|
auto s = std::make_shared<NTCPSession> (*m_NTCPServer, peer.router);
|
||||||
std::string addr = address->host.to_string();
|
if(m_NTCPServer->UsingProxy())
|
||||||
|
{
|
||||||
|
NTCPServer::RemoteAddressType remote = NTCPServer::eIP4Address;
|
||||||
|
std::string addr = address->host.to_string();
|
||||||
|
|
||||||
if(address->host.is_v6())
|
if(address->host.is_v6())
|
||||||
remote = NTCPServer::eIP6Address;
|
remote = NTCPServer::eIP6Address;
|
||||||
|
|
||||||
m_NTCPServer->ConnectWithProxy(addr, address->port, remote, s);
|
m_NTCPServer->ConnectWithProxy(addr, address->port, remote, s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_NTCPServer->Connect (address->host, address->port, s);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_NTCPServer->Connect (address->host, address->port, s);
|
{
|
||||||
return true;
|
LogPrint(eLogWarning, "Transports: NTCP Limit hit falling back to SSU");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // we don't have address
|
else // we don't have address
|
||||||
|
Loading…
Reference in New Issue
Block a user