From 2a01ad953cc74f08cf50dc7ee33c7725cc76a1f2 Mon Sep 17 00:00:00 2001 From: R4SAS Date: Mon, 12 Dec 2022 08:12:23 +0300 Subject: [PATCH] calculate bandwidth every 1 and 15 seconds Signed-off-by: R4SAS --- daemon/HTTPServer.cpp | 6 ++-- daemon/I2PControlHandlers.cpp | 14 ++++++++ daemon/I2PControlHandlers.h | 2 ++ libi2pd/Transports.cpp | 63 +++++++++++++++++++++++------------ libi2pd/Transports.h | 16 +++++++-- 5 files changed, 74 insertions(+), 27 deletions(-) diff --git a/daemon/HTTPServer.cpp b/daemon/HTTPServer.cpp index 7a6c5c12..917acdb8 100644 --- a/daemon/HTTPServer.cpp +++ b/daemon/HTTPServer.cpp @@ -290,13 +290,13 @@ namespace http { s << "" << tr("Tunnel creation success rate") << ": " << i2p::tunnel::tunnels.GetTunnelCreationSuccessRate () << "%
\r\n"; s << "" << tr("Received") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalReceivedBytes ()); - s << " (" << (double) i2p::transport::transports.GetInBandwidth () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; + s << " (" << (double) i2p::transport::transports.GetInBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; s << "" << tr("Sent") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalSentBytes ()); - s << " (" << (double) i2p::transport::transports.GetOutBandwidth () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; + s << " (" << (double) i2p::transport::transports.GetOutBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; s << "" << tr("Transit") << ": "; ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ()); - s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; + s << " (" << (double) i2p::transport::transports.GetTransitBandwidth15s () / 1024 << " " << tr(/* tr: Kibibit/s */ "KiB/s") << ")
\r\n"; s << "" << tr("Data path") << ": " << i2p::fs::GetUTF8DataDir() << "
\r\n"; s << "
"; if ((outputFormat == OutputFormatEnum::forWebConsole) || !includeHiddenContent) { diff --git a/daemon/I2PControlHandlers.cpp b/daemon/I2PControlHandlers.cpp index 15763948..f3ea7f61 100644 --- a/daemon/I2PControlHandlers.cpp +++ b/daemon/I2PControlHandlers.cpp @@ -33,7 +33,9 @@ namespace client m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlHandlers::NetDbKnownPeersHandler; m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlHandlers::NetDbActivePeersHandler; m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlHandlers::InboundBandwidth1S; + m_RouterInfoHandlers["i2p.router.net.bw.inbound.15s"] = &I2PControlHandlers::InboundBandwidth15S; m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlHandlers::OutboundBandwidth1S; + m_RouterInfoHandlers["i2p.router.net.bw.outbound.15s"] = &I2PControlHandlers::OutboundBandwidth15S; m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlHandlers::NetStatusHandler; m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlHandlers::TunnelsParticipatingHandler; m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlHandlers::TunnelsSuccessRateHandler; @@ -153,12 +155,24 @@ namespace client InsertParam (results, "i2p.router.net.bw.inbound.1s", bw); } + void I2PControlHandlers::InboundBandwidth15S (std::ostringstream& results) + { + double bw = i2p::transport::transports.GetInBandwidth15s (); + InsertParam (results, "i2p.router.net.bw.inbound.15s", bw); + } + void I2PControlHandlers::OutboundBandwidth1S (std::ostringstream& results) { double bw = i2p::transport::transports.GetOutBandwidth (); InsertParam (results, "i2p.router.net.bw.outbound.1s", bw); } + void I2PControlHandlers::OutboundBandwidth15S (std::ostringstream& results) + { + double bw = i2p::transport::transports.GetOutBandwidth15s (); + InsertParam (results, "i2p.router.net.bw.outbound.15s", bw); + } + void I2PControlHandlers::NetTotalReceivedBytes (std::ostringstream& results) { InsertParam (results, "i2p.router.net.total.received.bytes", (double)i2p::transport::transports.GetTotalReceivedBytes ()); diff --git a/daemon/I2PControlHandlers.h b/daemon/I2PControlHandlers.h index e33a19fc..d106f288 100644 --- a/daemon/I2PControlHandlers.h +++ b/daemon/I2PControlHandlers.h @@ -50,7 +50,9 @@ namespace client void TunnelsParticipatingHandler (std::ostringstream& results); void TunnelsSuccessRateHandler (std::ostringstream& results); void InboundBandwidth1S (std::ostringstream& results); + void InboundBandwidth15S (std::ostringstream& results); void OutboundBandwidth1S (std::ostringstream& results); + void OutboundBandwidth15S (std::ostringstream& results); void NetTotalReceivedBytes (std::ostringstream& results); void NetTotalSentBytes (std::ostringstream& results); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 34fcc065..8c15480d 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -136,12 +136,14 @@ namespace transport Transports::Transports (): m_IsOnline (true), m_IsRunning (false), m_IsNAT (true), m_CheckReserved(true), m_Thread (nullptr), m_Service (nullptr), m_Work (nullptr), m_PeerCleanupTimer (nullptr), m_PeerTestTimer (nullptr), - m_SSU2Server (nullptr), m_NTCP2Server (nullptr), + m_UpdateBandwidthTimer (nullptr), m_SSU2Server (nullptr), m_NTCP2Server (nullptr), m_X25519KeysPairSupplier (15), // 15 pre-generated keys - m_TotalSentBytes(0), m_TotalReceivedBytes(0), m_TotalTransitTransmittedBytes (0), - m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth(0), - m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), - m_LastTransitBandwidthUpdateBytes (0), m_LastBandwidthUpdateTime (0) + m_TotalSentBytes (0), m_TotalReceivedBytes (0), m_TotalTransitTransmittedBytes (0), + m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth (0), + m_LastInBandwidthUpdateBytes (0), m_LastOutBandwidthUpdateBytes (0), m_LastTransitBandwidthUpdateBytes (0), + m_InBandwidth15s (0), m_OutBandwidth15s (0), m_TransitBandwidth15s (0), + m_LastInBandwidth15sUpdateBytes (0), m_LastOutBandwidth15sUpdateBytes (0), m_LastTransitBandwidth15sUpdateBytes (0), + m_LastBandwidth15sUpdateTime (0) { } @@ -152,6 +154,7 @@ namespace transport { delete m_PeerCleanupTimer; m_PeerCleanupTimer = nullptr; delete m_PeerTestTimer; m_PeerTestTimer = nullptr; + delete m_UpdateBandwidthTimer; m_UpdateBandwidthTimer = nullptr; delete m_Work; m_Work = nullptr; delete m_Service; m_Service = nullptr; } @@ -165,6 +168,7 @@ namespace transport m_Work = new boost::asio::io_service::work (*m_Service); m_PeerCleanupTimer = new boost::asio::deadline_timer (*m_Service); m_PeerTestTimer = new boost::asio::deadline_timer (*m_Service); + m_UpdateBandwidthTimer = new boost::asio::steady_timer (*m_Service); } bool ipv4; i2p::config::GetOption("ipv4", ipv4); @@ -299,9 +303,12 @@ namespace transport if (m_SSU2Server) m_SSU2Server->Start (); if (m_SSU2Server) DetectExternalIP (); - m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT)); + m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5 * SESSION_CREATION_TIMEOUT)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1)); + m_UpdateBandwidthTimer->expires_from_now (std::chrono::seconds(1)); + m_UpdateBandwidthTimer->async_wait (std::bind (&Transports::HandleUpdateBandwidthTimer, this, std::placeholders::_1)); + if (m_IsNAT) { m_PeerTestTimer->expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL)); @@ -357,23 +364,38 @@ namespace transport } } - void Transports::UpdateBandwidth () + void Transports::HandleUpdateBandwidthTimer (const boost::system::error_code& ecode) { - uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); - if (m_LastBandwidthUpdateTime > 0) + if (ecode != boost::asio::error::operation_aborted) { - auto delta = ts - m_LastBandwidthUpdateTime; - if (delta > 0) + uint64_t ts = i2p::util::GetMillisecondsSinceEpoch (); + + // updated every second + m_InBandwidth = m_TotalReceivedBytes - m_LastInBandwidthUpdateBytes; + m_OutBandwidth = m_TotalSentBytes - m_LastOutBandwidthUpdateBytes; + m_TransitBandwidth = m_TotalTransitTransmittedBytes - m_LastTransitBandwidthUpdateBytes; + + m_LastInBandwidthUpdateBytes = m_TotalReceivedBytes; + m_LastOutBandwidthUpdateBytes = m_TotalSentBytes; + m_LastTransitBandwidthUpdateBytes = m_TotalTransitTransmittedBytes; + + // updated every 15 seconds + auto delta = ts - m_LastBandwidth15sUpdateTime; + if (delta > 15 * 1000) { - m_InBandwidth = (m_TotalReceivedBytes - m_LastInBandwidthUpdateBytes)*1000/delta; // per second - m_OutBandwidth = (m_TotalSentBytes - m_LastOutBandwidthUpdateBytes)*1000/delta; // per second - m_TransitBandwidth = (m_TotalTransitTransmittedBytes - m_LastTransitBandwidthUpdateBytes)*1000/delta; + m_InBandwidth15s = (m_TotalReceivedBytes - m_LastInBandwidth15sUpdateBytes) * 1000 / delta; + m_OutBandwidth15s = (m_TotalSentBytes - m_LastOutBandwidth15sUpdateBytes) * 1000 / delta; + m_TransitBandwidth15s = (m_TotalTransitTransmittedBytes - m_LastTransitBandwidth15sUpdateBytes) * 1000 / delta; + + m_LastBandwidth15sUpdateTime = ts; + m_LastInBandwidth15sUpdateBytes = m_TotalReceivedBytes; + m_LastOutBandwidth15sUpdateBytes = m_TotalSentBytes; + m_LastTransitBandwidth15sUpdateBytes = m_TotalTransitTransmittedBytes; } + + m_UpdateBandwidthTimer->expires_from_now (std::chrono::seconds(1)); + m_UpdateBandwidthTimer->async_wait (std::bind (&Transports::HandleUpdateBandwidthTimer, this, std::placeholders::_1)); } - m_LastBandwidthUpdateTime = ts; - m_LastInBandwidthUpdateBytes = m_TotalReceivedBytes; - m_LastOutBandwidthUpdateBytes = m_TotalSentBytes; - m_LastTransitBandwidthUpdateBytes = m_TotalTransitTransmittedBytes; } bool Transports::IsBandwidthExceeded () const @@ -745,7 +767,7 @@ namespace transport { it->second.sessions.remove_if ( [](std::shared_ptr session)->bool - { + { return !session || !session->IsEstablished (); }); if (it->second.sessions.empty () && ts > it->second.creationTime + SESSION_CREATION_TIMEOUT) @@ -772,13 +794,12 @@ namespace transport ++it; } } - UpdateBandwidth (); // TODO: use separate timer(s) for it bool ipv4Testing = i2p::context.GetStatus () == eRouterStatusTesting; bool ipv6Testing = i2p::context.GetStatusV6 () == eRouterStatusTesting; // if still testing, repeat peer test if (ipv4Testing || ipv6Testing) PeerTest (ipv4Testing, ipv6Testing); - m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(3*SESSION_CREATION_TIMEOUT)); + m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(3 * SESSION_CREATION_TIMEOUT)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1)); } } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 05fc5458..06527ffc 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -124,6 +124,9 @@ namespace transport uint32_t GetInBandwidth () const { return m_InBandwidth; }; uint32_t GetOutBandwidth () const { return m_OutBandwidth; }; uint32_t GetTransitBandwidth () const { return m_TransitBandwidth; }; + uint32_t GetInBandwidth15s () const { return m_InBandwidth15s; }; + uint32_t GetOutBandwidth15s () const { return m_OutBandwidth15s; }; + uint32_t GetTransitBandwidth15s () const { return m_TransitBandwidth15s; }; bool IsBandwidthExceeded () const; bool IsTransitBandwidthExceeded () const; size_t GetNumPeers () const { return m_Peers.size (); }; @@ -155,8 +158,8 @@ namespace transport void SetPriority (Peer& peer) const; void HandlePeerCleanupTimer (const boost::system::error_code& ecode); void HandlePeerTestTimer (const boost::system::error_code& ecode); + void HandleUpdateBandwidthTimer (const boost::system::error_code& ecode); - void UpdateBandwidth (); void DetectExternalIP (); private: @@ -167,6 +170,7 @@ namespace transport boost::asio::io_service * m_Service; boost::asio::io_service::work * m_Work; boost::asio::deadline_timer * m_PeerCleanupTimer, * m_PeerTestTimer; + boost::asio::steady_timer * m_UpdateBandwidthTimer; SSU2Server * m_SSU2Server; NTCP2Server * m_NTCP2Server; @@ -176,9 +180,15 @@ namespace transport X25519KeysPairSupplier m_X25519KeysPairSupplier; std::atomic m_TotalSentBytes, m_TotalReceivedBytes, m_TotalTransitTransmittedBytes; - uint32_t m_InBandwidth, m_OutBandwidth, m_TransitBandwidth; // bytes per second + + // Bandwidth per second + uint32_t m_InBandwidth, m_OutBandwidth, m_TransitBandwidth; uint64_t m_LastInBandwidthUpdateBytes, m_LastOutBandwidthUpdateBytes, m_LastTransitBandwidthUpdateBytes; - uint64_t m_LastBandwidthUpdateTime; + + // Bandwidth every 15 seconds + uint32_t m_InBandwidth15s, m_OutBandwidth15s, m_TransitBandwidth15s; + uint64_t m_LastInBandwidth15sUpdateBytes, m_LastOutBandwidth15sUpdateBytes, m_LastTransitBandwidth15sUpdateBytes; + uint64_t m_LastBandwidth15sUpdateTime; /** which router families to trust for first hops */ std::vector m_TrustedFamilies;