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;