diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index 3b2c204e..198f798b 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -396,8 +396,26 @@ namespace i2p return false; } uint8_t retCode = 0; + // decide if we should accept tunnel + bool accept = i2p::context.AcceptsTunnels (); + if (accept) + { + auto congestionLevel = i2p::context.GetCongestionLevel (false); + if (congestionLevel >= CONGESTION_LEVEL_MEDIUM) + { + if (congestionLevel < CONGESTION_LEVEL_FULL) + { + // random reject depending on congestion level + int level = i2p::tunnel::tunnels.GetRng ()() % (CONGESTION_LEVEL_FULL - CONGESTION_LEVEL_MEDIUM) + CONGESTION_LEVEL_MEDIUM; + if (congestionLevel > level) + accept = false; + } + else + accept = false; + } + } // replace record to reply - if (i2p::context.AcceptsTunnels () && i2p::context.GetCongestionLevel (false) < CONGESTION_LEVEL_FULL) + if (accept) { auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 1efb25db..f5f8b4fb 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -1489,7 +1489,7 @@ namespace i2p void RouterContext::UpdateCongestion () { auto c = i2p::data::RouterInfo::eLowCongestion; - if (!AcceptsTunnels () || !m_ShareRatio) + if (!AcceptsTunnels () || !m_ShareRatio || (m_Error == eRouterErrorSymmetricNAT && !SupportsV6 () && !SupportsMesh ())) c = i2p::data::RouterInfo::eRejectAll; else { diff --git a/libi2pd/Tunnel.cpp b/libi2pd/Tunnel.cpp index c41bb775..1e2a75d9 100644 --- a/libi2pd/Tunnel.cpp +++ b/libi2pd/Tunnel.cpp @@ -350,7 +350,8 @@ namespace tunnel Tunnels::Tunnels (): m_IsRunning (false), m_Thread (nullptr), m_MaxNumTransitTunnels (DEFAULT_MAX_NUM_TRANSIT_TUNNELS), m_TotalNumSuccesiveTunnelCreations (0), m_TotalNumFailedTunnelCreations (0), // for normal average - m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0) + m_TunnelCreationSuccessRate (TCSR_START_VALUE), m_TunnelCreationAttemptsNum(0), + m_Rng(i2p::util::GetMonotonicMicroseconds ()%1000000LL) { } diff --git a/libi2pd/Tunnel.h b/libi2pd/Tunnel.h index 00a05386..02bfb374 100644 --- a/libi2pd/Tunnel.h +++ b/libi2pd/Tunnel.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "util.h" #include "Queue.h" #include "Crypto.h" @@ -244,6 +245,8 @@ namespace tunnel uint32_t GetMaxNumTransitTunnels () const { return m_MaxNumTransitTunnels; }; int GetCongestionLevel() const { return m_MaxNumTransitTunnels ? CONGESTION_LEVEL_FULL * m_TransitTunnels.size() / m_MaxNumTransitTunnels : CONGESTION_LEVEL_FULL; } + std::mt19937& GetRng () { return m_Rng; }; + private: template @@ -307,6 +310,7 @@ namespace tunnel int m_TotalNumSuccesiveTunnelCreations, m_TotalNumFailedTunnelCreations; double m_TunnelCreationSuccessRate; int m_TunnelCreationAttemptsNum; + std::mt19937 m_Rng; public: