From 716926f0d7f22a203c21355e837a2d7e6ed508c3 Mon Sep 17 00:00:00 2001 From: orignal Date: Mon, 6 Mar 2023 19:48:04 -0500 Subject: [PATCH] publish high congestion cap --- libi2pd/I2NPProtocol.cpp | 12 +++--------- libi2pd/RouterContext.cpp | 33 +++++++++++++++++++++++++++++++++ libi2pd/RouterContext.h | 6 +++++- libi2pd/RouterInfo.cpp | 18 +++++++++++++++++- libi2pd/RouterInfo.h | 8 +++++--- 5 files changed, 63 insertions(+), 14 deletions(-) diff --git a/libi2pd/I2NPProtocol.cpp b/libi2pd/I2NPProtocol.cpp index c1724b39..5ae89c23 100644 --- a/libi2pd/I2NPProtocol.cpp +++ b/libi2pd/I2NPProtocol.cpp @@ -364,10 +364,7 @@ namespace i2p if (!i2p::context.DecryptTunnelBuildRecord (record + BUILD_REQUEST_RECORD_ENCRYPTED_OFFSET, clearText)) return false; uint8_t retCode = 0; // replace record to reply - if (i2p::context.AcceptsTunnels () && - !i2p::tunnel::tunnels.IsTooManyTransitTunnels () && - !i2p::transport::transports.IsBandwidthExceeded () && - !i2p::transport::transports.IsTransitBandwidthExceeded ()) + if (i2p::context.AcceptsTunnels () && !i2p::context.IsHighCongestion ()) { auto transitTunnel = i2p::tunnel::CreateTransitTunnel ( bufbe32toh (clearText + ECIES_BUILD_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET), @@ -561,11 +558,8 @@ namespace i2p // check if we accept this tunnel uint8_t retCode = 0; - if (!i2p::context.AcceptsTunnels () || - i2p::tunnel::tunnels.IsTooManyTransitTunnels () || - i2p::transport::transports.IsBandwidthExceeded () || - i2p::transport::transports.IsTransitBandwidthExceeded ()) - retCode = 30; + if (!i2p::context.AcceptsTunnels () || i2p::context.IsHighCongestion ()) + retCode = 30; if (!retCode) { // create new transit tunnel diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index f2b8f4fb..b6806fb3 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -60,6 +60,8 @@ namespace i2p { m_PublishTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ())); ScheduleInitialPublish (); + m_CongestionUpdateTimer.reset (new boost::asio::deadline_timer (m_Service->GetService ())); + ScheduleCongestionUpdate (); } } } @@ -70,6 +72,8 @@ namespace i2p { if (m_PublishTimer) m_PublishTimer->cancel (); + if (m_CongestionUpdateTimer) + m_CongestionUpdateTimer->cancel (); m_Service->Stop (); } } @@ -1107,6 +1111,13 @@ namespace i2p return i2p::tunnel::tunnels.GetExploratoryPool (); } + bool RouterContext::IsHighCongestion () const + { + return i2p::tunnel::tunnels.IsTooManyTransitTunnels () || + i2p::transport::transports.IsBandwidthExceeded () || + i2p::transport::transports.IsTransitBandwidthExceeded (); + } + void RouterContext::HandleI2NPMessage (const uint8_t * buf, size_t len) { i2p::HandleI2NPMessage (CreateI2NPMessage (buf, GetI2NPMessageLength (buf, len))); @@ -1368,4 +1379,26 @@ namespace i2p SchedulePublishResend (); } } + + void RouterContext::ScheduleCongestionUpdate () + { + if (m_CongestionUpdateTimer) + { + m_CongestionUpdateTimer->cancel (); + m_CongestionUpdateTimer->expires_from_now (boost::posix_time::seconds(ROUTER_INFO_CONGESTION_UPDATE_INTERVAL)); + m_CongestionUpdateTimer->async_wait (std::bind (&RouterContext::HandleCongestionUpdateTimer, + this, std::placeholders::_1)); + } + else + LogPrint (eLogError, "Router: Congestion update timer is NULL"); + } + + void RouterContext::HandleCongestionUpdateTimer (const boost::system::error_code& ecode) + { + if (ecode != boost::asio::error::operation_aborted) + { + m_RouterInfo.SetHighCongestion (IsHighCongestion ()); + ScheduleCongestionUpdate (); + } + } } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index 4b6d917e..b8183339 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -37,6 +37,7 @@ namespace garlic const int ROUTER_INFO_PUBLISH_INTERVAL_VARIANCE = 105;// in seconds const int ROUTER_INFO_CONFIRMATION_TIMEOUT = 5; // in seconds const int ROUTER_INFO_MAX_PUBLISH_EXCLUDED_FLOODFILLS = 15; + const int ROUTER_INFO_CONGESTION_UPDATE_INTERVAL = 12*60; // in seconds enum RouterStatus { @@ -152,6 +153,7 @@ namespace garlic void SetShareRatio (int percents); // 0 - 100 bool AcceptsTunnels () const { return m_AcceptsTunnels; }; void SetAcceptsTunnels (bool acceptsTunnels) { m_AcceptsTunnels = acceptsTunnels; }; + bool IsHighCongestion () const; bool SupportsV6 () const { return m_RouterInfo.IsV6 (); }; bool SupportsV4 () const { return m_RouterInfo.IsV4 (); }; bool SupportsMesh () const { return m_RouterInfo.IsMesh (); }; @@ -213,6 +215,8 @@ namespace garlic void Publish (); void SchedulePublishResend (); void HandlePublishResendTimer (const boost::system::error_code& ecode); + void ScheduleCongestionUpdate (); + void HandleCongestionUpdateTimer (const boost::system::error_code& ecode); private: @@ -235,7 +239,7 @@ namespace garlic i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState; // publish std::unique_ptr m_Service; - std::unique_ptr m_PublishTimer; + std::unique_ptr m_PublishTimer, m_CongestionUpdateTimer; std::set m_PublishExcluded; uint32_t m_PublishReplyToken; bool m_IsHiddenMode; // not publish diff --git a/libi2pd/RouterInfo.cpp b/libi2pd/RouterInfo.cpp index e9df01bb..41c69b09 100644 --- a/libi2pd/RouterInfo.cpp +++ b/libi2pd/RouterInfo.cpp @@ -1071,9 +1071,15 @@ namespace data if (m_Congestion == eLowCongestion || m_Congestion == eMediumCongestion) return false; if (m_Congestion == eRejectAll) return true; if (m_Congestion == eHighCongestion) - return (i2p::util::GetMillisecondsSinceEpoch () < m_Timestamp + HIGH_CONGESION_INTERVAL*1000LL) ? true : false; + return (i2p::util::GetMillisecondsSinceEpoch () < m_Timestamp + HIGH_CONGESTION_INTERVAL*1000LL) ? true : false; return false; } + + LocalRouterInfo::LocalRouterInfo (const std::string& fullPath): + RouterInfo (fullPath) + { + SetHighCongestion (false); // drop congestion + } void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys) { @@ -1143,6 +1149,16 @@ namespace data SetProperty ("caps", caps); } + void LocalRouterInfo::SetHighCongestion (bool highCongestion) + { + Congestion c = highCongestion ? eHighCongestion : eLowCongestion; + if (c != GetCongestion ()) + { + SetCongestion (c); + UpdateCapsProperty (); + } + } + void LocalRouterInfo::WriteToStream (std::ostream& s) const { auto addresses = GetAddresses (); diff --git a/libi2pd/RouterInfo.h b/libi2pd/RouterInfo.h index 3b74eaf3..2e9e67b5 100644 --- a/libi2pd/RouterInfo.h +++ b/libi2pd/RouterInfo.h @@ -60,7 +60,7 @@ namespace data const uint8_t COST_SSU2_NON_PUBLISHED = 15; const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later - const int HIGH_CONGESION_INTERVAL = 15*60; // in seconds, 15 minutes + const int HIGH_CONGESTION_INTERVAL = 15*60; // in seconds, 15 minutes class RouterInfo: public RoutingDestination { @@ -291,7 +291,8 @@ namespace data void RefreshTimestamp (); CompatibleTransports GetReachableTransports () const { return m_ReachableTransports; }; void SetReachableTransports (CompatibleTransports transports) { m_ReachableTransports = transports; }; - + void SetCongestion (Congestion c) { m_Congestion = c; }; + private: bool LoadFile (const std::string& fullPath); @@ -328,9 +329,10 @@ namespace data public: LocalRouterInfo () = default; - LocalRouterInfo (const std::string& fullPath): RouterInfo (fullPath) {}; + LocalRouterInfo (const std::string& fullPath); void CreateBuffer (const PrivateKeys& privateKeys); void UpdateCaps (uint8_t caps); + void SetHighCongestion (bool highCongestion); void SetProperty (const std::string& key, const std::string& value) override; void DeleteProperty (const std::string& key);