@@ -1703,18 +1703,19 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
17031703 //
17041704 CAddress addrConnect;
17051705
1706- // Only connect out to one peer per network group (/16 for IPv4).
1706+ // Only connect out to one peer per ipv4/ipv6 network group (/16 for IPv4).
17071707 int nOutboundFullRelay = 0 ;
17081708 int nOutboundBlockRelay = 0 ;
1709- std::set<std::vector<unsigned char > > setConnected;
1709+ int outbound_privacy_network_peers = 0 ;
1710+ std::set<std::vector<unsigned char >> setConnected; // netgroups of our ipv4/ipv6 outbound peers
17101711
17111712 {
17121713 LOCK (m_nodes_mutex);
17131714 for (const CNode* pnode : m_nodes) {
17141715 if (pnode->IsFullOutboundConn ()) nOutboundFullRelay++;
17151716 if (pnode->IsBlockOnlyConn ()) nOutboundBlockRelay++;
17161717
1717- // Make sure our persistent outbound slots belong to different netgroups.
1718+ // Make sure our persistent outbound slots to ipv4/ipv6 peers belong to different netgroups.
17181719 switch (pnode->m_conn_type ) {
17191720 // We currently don't take inbound connections into account. Since they are
17201721 // free to make, an attacker could make them to prevent us from connecting to
@@ -1728,7 +1729,19 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
17281729 case ConnectionType::MANUAL:
17291730 case ConnectionType::OUTBOUND_FULL_RELAY:
17301731 case ConnectionType::BLOCK_RELAY:
1731- setConnected.insert (m_netgroupman.GetGroup (pnode->addr ));
1732+ CAddress address{pnode->addr };
1733+ if (address.IsTor () || address.IsI2P () || address.IsCJDNS ()) {
1734+ // Since our addrman-groups for these networks are
1735+ // random, without relation to the route we
1736+ // take to connect to these peers or to the
1737+ // difficulty in obtaining addresses with diverse
1738+ // groups, we don't worry about diversity with
1739+ // respect to our addrman groups when connecting to
1740+ // these networks.
1741+ ++outbound_privacy_network_peers;
1742+ } else {
1743+ setConnected.insert (m_netgroupman.GetGroup (address));
1744+ }
17321745 } // no default case, so the compiler can warn about missing cases
17331746 }
17341747 }
@@ -1886,8 +1899,11 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
18861899 }
18871900 LogPrint (BCLog::NET, " Making feeler connection to %s\n " , addrConnect.ToStringAddrPort ());
18881901 }
1889-
1890- OpenNetworkConnection (addrConnect, (int )setConnected.size () >= std::min (nMaxConnections - 1 , 2 ), &grant, nullptr , conn_type);
1902+ // Record addrman failure attempts when node has at least 2 persistent outbound connections to peers with
1903+ // different netgroups in ipv4/ipv6 networks + all peers in Tor/I2P/CJDNS networks.
1904+ // Don't record addrman failure attempts when node is offline. This can be identified since all local
1905+ // network connections(if any) belong in the same netgroup and size of setConnected would only be 1.
1906+ OpenNetworkConnection (addrConnect, (int )setConnected.size () + outbound_privacy_network_peers >= std::min (nMaxConnections - 1 , 2 ), &grant, nullptr , conn_type);
18911907 }
18921908 }
18931909}
0 commit comments