From 124e2e759c54b37bc4af8c33344e2cf4c3c12453 Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 4 May 2017 14:58:12 -0400 Subject: [PATCH] fix #846. ability to limit transit bandwidth --- daemon/Daemon.cpp | 3 +++ libi2pd/Config.cpp | 1 + libi2pd/I2NPProtocol.cpp | 3 ++- libi2pd/RouterContext.cpp | 11 +++++++++-- libi2pd/RouterContext.h | 5 ++++- libi2pd/Transports.cpp | 6 ++++++ libi2pd/Transports.h | 1 + 7 files changed, 26 insertions(+), 4 deletions(-) diff --git a/daemon/Daemon.cpp b/daemon/Daemon.cpp index a4c6e4e2..7b1cc361 100644 --- a/daemon/Daemon.cpp +++ b/daemon/Daemon.cpp @@ -189,6 +189,9 @@ namespace i2p i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2); } + int shareRatio; i2p::config::GetOption("share", shareRatio); + i2p::context.SetShareRatio (shareRatio); + std::string family; i2p::config::GetOption("family", family); i2p::context.SetFamily (family); if (family.length () > 0) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 14517a8d..796d4871 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -54,6 +54,7 @@ namespace config { ("notransit", value()->zero_tokens()->default_value(false), "Router will not accept transit tunnels at startup") ("floodfill", value()->zero_tokens()->default_value(false), "Router will be floodfill") ("bandwidth", value()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)") + ("share", value()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100") ("ntcp", value()->zero_tokens()->default_value(true), "Enable NTCP transport") ("ssu", value()->zero_tokens()->default_value(true), "Enable SSU transport") #ifdef _WIN32 diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 96607de2..9f7738f3 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -332,7 +332,8 @@ namespace i2p // replace record to reply if (i2p::context.AcceptsTunnels () && i2p::tunnel::tunnels.GetTransitTunnels ().size () <= g_MaxNumTransitTunnels && - !i2p::transport::transports.IsBandwidthExceeded ()) + !i2p::transport::transports.IsBandwidthExceeded () && + !i2p::transport::transports.IsTransitBandwidthExceeded ()) { auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 75fc9f33..7be25b04 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -17,8 +17,8 @@ namespace i2p RouterContext::RouterContext (): m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false), - m_StartupTime (0), m_Status (eRouterStatusOK), m_Error (eRouterErrorNone), - m_NetID (I2PD_NET_ID) + m_StartupTime (0), m_ShareRatio (100), m_Status (eRouterStatusOK), + m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID) { } @@ -246,6 +246,13 @@ namespace i2p else { SetBandwidth('K'); } } + void RouterContext::SetShareRatio (int percents) + { + if (percents < 0) percents = 0; + if (percents > 100) percents = 100; + m_ShareRatio = percents; + } + bool RouterContext::IsUnreachable () const { return m_RouterInfo.GetCaps () & i2p::data::RouterInfo::eUnreachable; diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 7ce310ee..b3146b56 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -54,6 +54,7 @@ namespace i2p uint32_t GetStartupTime () const { return m_StartupTime; }; uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; }; uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; }; + uint64_t GetTransitBandwidthLimit () const { return (m_BandwidthLimit*m_ShareRatio)/100LL; }; RouterStatus GetStatus () const { return m_Status; }; void SetStatus (RouterStatus status); RouterError GetError () const { return m_Error; }; @@ -74,6 +75,7 @@ namespace i2p std::string GetFamily () const; void SetBandwidth (int limit); /* in kilobytes */ void SetBandwidth (char L); /* by letter */ + void SetShareRatio (int percents); // 0 - 100 bool AcceptsTunnels () const { return m_AcceptsTunnels; }; void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; }; bool SupportsV6 () const { return m_RouterInfo.IsV6 (); }; @@ -116,7 +118,8 @@ namespace i2p uint64_t m_LastUpdateTime; bool m_AcceptsTunnels, m_IsFloodfill; uint64_t m_StartupTime; // in seconds since epoch - uint32_t m_BandwidthLimit; // allowed bandwidth + uint64_t m_BandwidthLimit; // allowed bandwidth + int m_ShareRatio; RouterStatus m_Status; RouterError m_Error; int m_NetID; diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 993b3e64..ef885e46 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -261,6 +261,12 @@ namespace transport return bw > limit; } + bool Transports::IsTransitBandwidthExceeded () const + { + auto limit = i2p::context.GetTransitBandwidthLimit() * 1024; // convert to bytes + return m_TransitBandwidth > limit; + } + void Transports::SendMessage (const i2p::data::IdentHash& ident, std::shared_ptr msg) { SendMessages (ident, std::vector > {msg }); diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 8cc97d22..b05f1eab 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -106,6 +106,7 @@ namespace transport uint32_t GetOutBandwidth () const { return m_OutBandwidth; }; uint32_t GetTransitBandwidth () const { return m_TransitBandwidth; }; bool IsBandwidthExceeded () const; + bool IsTransitBandwidthExceeded () const; size_t GetNumPeers () const { return m_Peers.size (); }; std::shared_ptr GetRandomPeer () const;