| 1273 | } |
| 1274 | |
| 1275 | bool CConnman::AddConnection(const std::string& address, ConnectionType conn_type) |
| 1276 | { |
| 1277 | std::optional<int> max_connections; |
| 1278 | switch (conn_type) { |
| 1279 | case ConnectionType::INBOUND: |
| 1280 | case ConnectionType::MANUAL: |
| 1281 | return false; |
| 1282 | case ConnectionType::OUTBOUND_FULL_RELAY: |
| 1283 | max_connections = m_max_outbound_full_relay; |
| 1284 | break; |
| 1285 | case ConnectionType::BLOCK_RELAY: |
| 1286 | max_connections = m_max_outbound_block_relay; |
| 1287 | break; |
| 1288 | // no limit for ADDR_FETCH because -seednode has no limit either |
| 1289 | case ConnectionType::ADDR_FETCH: |
| 1290 | break; |
| 1291 | // no limit for FEELER connections since they're short-lived |
| 1292 | case ConnectionType::FEELER: |
| 1293 | break; |
| 1294 | } // no default case, so the compiler can warn about missing cases |
| 1295 | |
| 1296 | // Count existing connections |
| 1297 | int existing_connections = WITH_LOCK(m_nodes_mutex, |
| 1298 | return std::count_if(m_nodes.begin(), m_nodes.end(), [conn_type](CNode* node) { return node->m_conn_type == conn_type; });); |
| 1299 | |
| 1300 | // Max connections of specified type already exist |
| 1301 | if (max_connections != std::nullopt && existing_connections >= max_connections) return false; |
| 1302 | |
| 1303 | // Max total outbound connections already exist |
| 1304 | CSemaphoreGrant grant(*semOutbound, true); |
| 1305 | if (!grant) return false; |
| 1306 | |
| 1307 | OpenNetworkConnection(CAddress(), false, &grant, address.c_str(), conn_type); |
| 1308 | return true; |
| 1309 | } |
| 1310 | |
| 1311 | void CConnman::DisconnectNodes() |
| 1312 | { |
no test coverage detected