@@ -2454,20 +2454,22 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
24542454 //
24552455 CAddress addrConnect;
24562456
2457- // Only connect out to one peer per network group (/16 for IPv4).
2457+ // Only connect out to one peer per ipv4/ipv6 network group (/16 for IPv4).
24582458 // This is only done for mainnet and testnet
24592459 int nOutboundFullRelay = 0 ;
24602460 int nOutboundBlockRelay = 0 ;
24612461 int nOutboundOnionRelay = 0 ;
2462- std::set<std::vector<unsigned char > > setConnected;
2462+ int outbound_privacy_network_peers = 0 ;
2463+ std::set<std::vector<unsigned char >> setConnected; // netgroups of our ipv4/ipv6 outbound peers
2464+
24632465 if (!Params ().AllowMultipleAddressesFromGroup ()) {
24642466 LOCK (m_nodes_mutex);
24652467 for (const CNode* pnode : m_nodes) {
24662468 if (pnode->IsFullOutboundConn () && !pnode->m_masternode_connection ) nOutboundFullRelay++;
24672469 if (pnode->IsBlockOnlyConn ()) nOutboundBlockRelay++;
24682470 if (pnode->IsFullOutboundConn () && pnode->ConnectedThroughNetwork () == Network::NET_ONION) nOutboundOnionRelay++;
24692471
2470- // Make sure our persistent outbound slots belong to different netgroups.
2472+ // Make sure our persistent outbound slots to ipv4/ipv6 peers belong to different netgroups.
24712473 switch (pnode->m_conn_type ) {
24722474 // We currently don't take inbound connections into account. Since they are
24732475 // free to make, an attacker could make them to prevent us from connecting to
@@ -2481,7 +2483,19 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
24812483 case ConnectionType::MANUAL:
24822484 case ConnectionType::OUTBOUND_FULL_RELAY:
24832485 case ConnectionType::BLOCK_RELAY:
2484- setConnected.insert (m_netgroupman.GetGroup (pnode->addr ));
2486+ CAddress address{pnode->addr };
2487+ if (address.IsTor () || address.IsI2P () || address.IsCJDNS ()) {
2488+ // Since our addrman-groups for these networks are
2489+ // random, without relation to the route we
2490+ // take to connect to these peers or to the
2491+ // difficulty in obtaining addresses with diverse
2492+ // groups, we don't worry about diversity with
2493+ // respect to our addrman groups when connecting to
2494+ // these networks.
2495+ ++outbound_privacy_network_peers;
2496+ } else {
2497+ setConnected.insert (m_netgroupman.GetGroup (address));
2498+ }
24852499 } // no default case, so the compiler can warn about missing cases
24862500 }
24872501 }
@@ -2675,8 +2689,11 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
26752689 LogPrint (BCLog::NET, " Making feeler connection\n " );
26762690 }
26772691 }
2678-
2679- OpenNetworkConnection (addrConnect, (int )setConnected.size () >= std::min (nMaxConnections - 1 , 2 ), &grant, nullptr , conn_type);
2692+ // Record addrman failure attempts when node has at least 2 persistent outbound connections to peers with
2693+ // different netgroups in ipv4/ipv6 networks + all peers in Tor/I2P/CJDNS networks.
2694+ // Don't record addrman failure attempts when node is offline. This can be identified since all local
2695+ // network connections(if any) belong in the same netgroup and size of setConnected would only be 1.
2696+ OpenNetworkConnection (addrConnect, (int )setConnected.size () + outbound_privacy_network_peers >= std::min (nMaxConnections - 1 , 2 ), &grant, nullptr , conn_type);
26802697 }
26812698 }
26822699}
0 commit comments