Try to find a connection to evict when the node is full. * Extreme care must be taken to avoid opening the node to attacker * triggered network partitioning. * The strategy used here is to protect a small number of peers * for each of several distinct characteristics which are difficult * to forge. In order to partition a node the attacker must be * simultaneously better at all of
| 1100 | * simultaneously better at all of them than honest peers. |
| 1101 | */ |
| 1102 | bool CConnman::AttemptToEvictConnection() |
| 1103 | { |
| 1104 | std::vector<NodeEvictionCandidate> vEvictionCandidates; |
| 1105 | { |
| 1106 | |
| 1107 | LOCK(m_nodes_mutex); |
| 1108 | for (const CNode* node : m_nodes) { |
| 1109 | if (node->HasPermission(NetPermissionFlags::NoBan)) |
| 1110 | continue; |
| 1111 | if (!node->IsInboundConn()) |
| 1112 | continue; |
| 1113 | if (node->fDisconnect) |
| 1114 | continue; |
| 1115 | bool peer_relay_txes = false; |
| 1116 | bool peer_filter_not_null = false; |
| 1117 | if (node->m_tx_relay != nullptr) { |
| 1118 | LOCK(node->m_tx_relay->cs_filter); |
| 1119 | peer_relay_txes = node->m_tx_relay->fRelayTxes; |
| 1120 | peer_filter_not_null = node->m_tx_relay->pfilter != nullptr; |
| 1121 | } |
| 1122 | NodeEvictionCandidate candidate = {node->GetId(), node->m_connected, node->m_min_ping_time, |
| 1123 | node->m_last_block_time, node->m_last_tx_time, |
| 1124 | HasAllDesirableServiceFlags(node->nServices), |
| 1125 | peer_relay_txes, peer_filter_not_null, node->nKeyedNetGroup, |
| 1126 | node->m_prefer_evict, node->addr.IsLocal(), |
| 1127 | node->ConnectedThroughNetwork()}; |
| 1128 | vEvictionCandidates.push_back(candidate); |
| 1129 | } |
| 1130 | } |
| 1131 | const std::optional<NodeId> node_id_to_evict = SelectNodeToEvict(std::move(vEvictionCandidates)); |
| 1132 | if (!node_id_to_evict) { |
| 1133 | return false; |
| 1134 | } |
| 1135 | LOCK(m_nodes_mutex); |
| 1136 | for (CNode* pnode : m_nodes) { |
| 1137 | if (pnode->GetId() == *node_id_to_evict) { |
| 1138 | LogPrint(BCLog::NET, "selected %s connection for eviction peer=%d; disconnecting\n", pnode->ConnectionTypeAsString(), pnode->GetId()); |
| 1139 | pnode->fDisconnect = true; |
| 1140 | return true; |
| 1141 | } |
| 1142 | } |
| 1143 | return false; |
| 1144 | } |
| 1145 | |
| 1146 | void CConnman::AcceptConnection(const ListenSocket& hListenSocket) { |
| 1147 | struct sockaddr_storage sockaddr; |
nothing calls this directly
no test coverage detected