diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 22646d94..8f632759 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -160,7 +160,8 @@ namespace transport m_TotalSentBytes (0), m_TotalReceivedBytes (0), m_TotalTransitTransmittedBytes (0), m_InBandwidth (0), m_OutBandwidth (0), m_TransitBandwidth (0), m_InBandwidth15s (0), m_OutBandwidth15s (0), m_TransitBandwidth15s (0), - m_InBandwidth5m (0), m_OutBandwidth5m (0), m_TransitBandwidth5m (0) + m_InBandwidth5m (0), m_OutBandwidth5m (0), m_TransitBandwidth5m (0), + m_Rng(i2p::util::GetMonotonicMicroseconds () % 1000000LL) { } @@ -338,7 +339,7 @@ namespace transport if (m_IsNAT) { - m_PeerTestTimer->expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL)); + m_PeerTestTimer->expires_from_now (boost::posix_time::seconds(PEER_TEST_INTERVAL + m_Rng() % PEER_TEST_INTERVAL_VARIANCE)); m_PeerTestTimer->async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1)); } } @@ -654,7 +655,7 @@ namespace transport return true; } - void Transports::SetPriority (std::shared_ptr peer) const + void Transports::SetPriority (std::shared_ptr peer) { static const std::vector ntcp2Priority = @@ -680,7 +681,7 @@ namespace transport peer->numAttempts = 0; peer->priority.clear (); bool isReal = peer->router->GetProfile ()->IsReal (); - bool ssu2 = isReal ? (rand () & 1) : false; // try NTCP2 if router is not confirmed real + bool ssu2 = isReal ? (m_Rng () & 1) : false; // try NTCP2 if router is not confirmed real const auto& priority = ssu2 ? ssu2Priority : ntcp2Priority; if (directTransports) { @@ -799,7 +800,7 @@ namespace transport } else { - testDelay += PEER_TEST_DELAY_INTERVAL + rand() % PEER_TEST_DELAY_INTERVAL_VARIANCE; + testDelay += PEER_TEST_DELAY_INTERVAL + m_Rng() % PEER_TEST_DELAY_INTERVAL_VARIANCE; if (m_Service) { auto delayTimer = std::make_shared(*m_Service); @@ -837,7 +838,7 @@ namespace transport } else { - testDelay += PEER_TEST_DELAY_INTERVAL + rand() % PEER_TEST_DELAY_INTERVAL_VARIANCE; + testDelay += PEER_TEST_DELAY_INTERVAL + m_Rng() % PEER_TEST_DELAY_INTERVAL_VARIANCE; if (m_Service) { auto delayTimer = std::make_shared(*m_Service); @@ -1027,7 +1028,7 @@ namespace transport if (session) session->SendLocalRouterInfo (true); it->second->nextRouterInfoUpdateTime = ts + PEER_ROUTER_INFO_UPDATE_INTERVAL + - rand () % PEER_ROUTER_INFO_UPDATE_INTERVAL_VARIANCE; + m_Rng() % PEER_ROUTER_INFO_UPDATE_INTERVAL_VARIANCE; } ++it; } @@ -1051,7 +1052,7 @@ namespace transport if (ecode != boost::asio::error::operation_aborted) { PeerTest (); - m_PeerTestTimer->expires_from_now (boost::posix_time::minutes(PEER_TEST_INTERVAL)); + m_PeerTestTimer->expires_from_now (boost::posix_time::seconds(PEER_TEST_INTERVAL + m_Rng() % PEER_TEST_INTERVAL_VARIANCE)); m_PeerTestTimer->async_wait (std::bind (&Transports::HandlePeerTestTimer, this, std::placeholders::_1)); } } @@ -1198,7 +1199,7 @@ namespace transport } /** XXX: if routes are not restricted this dies */ - std::shared_ptr Transports::GetRestrictedPeer() const + std::shared_ptr Transports::GetRestrictedPeer() { { std::lock_guard l(m_FamilyMutex); @@ -1207,7 +1208,7 @@ namespace transport if(sz > 1) { auto it = m_TrustedFamilies.begin (); - std::advance(it, rand() % sz); + std::advance(it, m_Rng() % sz); fam = *it; } else if (sz == 1) @@ -1225,7 +1226,7 @@ namespace transport if(sz == 1) return i2p::data::netdb.FindRouter(m_TrustedRouters[0]); auto it = m_TrustedRouters.begin(); - std::advance(it, rand() % sz); + std::advance(it, m_Rng() % sz); return i2p::data::netdb.FindRouter(*it); } } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index c1acbb2e..6f856697 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2024, The PurpleI2P Project +* Copyright (c) 2013-2025, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "TransportSession.h" #include "SSU2.h" @@ -106,7 +107,8 @@ namespace transport }; const uint64_t SESSION_CREATION_TIMEOUT = 15; // in seconds - const int PEER_TEST_INTERVAL = 71; // in minutes + const int PEER_TEST_INTERVAL = 68*60; // in seconds + const int PEER_TEST_INTERVAL_VARIANCE = 3*60; // in seconds const int PEER_TEST_DELAY_INTERVAL = 20; // in milliseconds const int PEER_TEST_DELAY_INTERVAL_VARIANCE = 30; // in milliseconds const int MAX_NUM_DELAYED_MESSAGES = 150; @@ -168,7 +170,7 @@ namespace transport std::shared_ptr GetRandomPeer (bool isHighBandwidth) const; /** get a trusted first hop for restricted routes */ - std::shared_ptr GetRestrictedPeer() const; + std::shared_ptr GetRestrictedPeer(); /** do we want to use restricted routes? */ bool RoutesRestricted() const; /** restrict routes to use only these router families for first hops */ @@ -191,7 +193,7 @@ namespace transport void HandleRequestComplete (std::shared_ptr r, i2p::data::IdentHash ident); std::shared_ptr PostMessages (const i2p::data::IdentHash& ident, std::list >& msgs); bool ConnectToPeer (const i2p::data::IdentHash& ident, std::shared_ptr peer); - void SetPriority (std::shared_ptr peer) const; + void SetPriority (std::shared_ptr peer); void HandlePeerCleanupTimer (const boost::system::error_code& ecode); void HandlePeerTestTimer (const boost::system::error_code& ecode); void HandleUpdateBandwidthTimer (const boost::system::error_code& ecode); @@ -239,6 +241,7 @@ namespace transport mutable std::mutex m_TrustedRoutersMutex; i2p::I2NPMessagesHandler m_LoopbackHandler; + std::mt19937 m_Rng; public: