diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index 87183637..a1dfb6db 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -1228,13 +1228,19 @@ namespace transport std::shared_ptr Transports::GetRandomPeer (bool isHighBandwidth) const { return GetRandomPeer ( - [isHighBandwidth](std::shared_ptr peer)->bool + [isHighBandwidth, this](std::shared_ptr peer)->bool { - // connected, not overloaded and not slow - return !peer->router && peer->IsConnected () && peer->isEligible && - peer->sessions.front ()->GetSendQueueSize () <= PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE && - !peer->sessions.front ()->IsSlow () && !peer->sessions.front ()->IsBandwidthExceeded (peer->isHighBandwidth) && - (!isHighBandwidth || peer->isHighBandwidth); + // check if connected and high bandwidth if required + if (peer->router || !peer->IsConnected () || !peer->isEligible || + peer->sessions.empty () || (isHighBandwidth && !peer->isHighBandwidth)) return false; + auto session = peer->sessions.front (); + // check if session not overloaded, slow or bandwidth exceeded + if (session->GetSendQueueSize () > PEER_ROUTER_INFO_OVERLOAD_QUEUE_SIZE || + session->IsSlow () || session->IsBandwidthExceeded (peer->isHighBandwidth)) return false; + // check if max num connections from subnet is not exceeded + auto it = m_ConnectedNetworks.find (GetNetworkAddress (session)); + if (it != m_ConnectedNetworks.end () && it->second > MAX_NUM_CONNECTIONS_FROM_SUBNET_FOR_PEER) return false; + return true; }); } diff --git a/libi2pd/Transports.h b/libi2pd/Transports.h index 8393624c..3dce8b3c 100644 --- a/libi2pd/Transports.h +++ b/libi2pd/Transports.h @@ -115,6 +115,7 @@ namespace transport const int MAX_NUM_DELAYED_MESSAGES = 150; const int CHECK_PROFILE_NUM_DELAYED_MESSAGES = 15; // check profile after const int NUM_X25519_PRE_GENERATED_KEYS = 25; // pre-generated x25519 keys pairs + const int MAX_NUM_CONNECTIONS_FROM_SUBNET_FOR_PEER = 3; // for first hop selection const int IP_BAN_TIME = 1800; // in seconds const int IP_BAN_TIME_VARIANCE = 540; // in seconds