| 1930 | } |
| 1931 | |
| 1932 | void CConnman::DisconnectNodes() |
| 1933 | { |
| 1934 | AssertLockNotHeld(m_nodes_mutex); |
| 1935 | AssertLockNotHeld(m_reconnections_mutex); |
| 1936 | |
| 1937 | // Use a temporary variable to accumulate desired reconnections, so we don't need |
| 1938 | // m_reconnections_mutex while holding m_nodes_mutex. |
| 1939 | decltype(m_reconnections) reconnections_to_add; |
| 1940 | |
| 1941 | { |
| 1942 | LOCK(m_nodes_mutex); |
| 1943 | |
| 1944 | const bool network_active{fNetworkActive}; |
| 1945 | if (!network_active) { |
| 1946 | // Disconnect any connected nodes |
| 1947 | for (CNode* pnode : m_nodes) { |
| 1948 | if (!pnode->fDisconnect) { |
| 1949 | LogDebug(BCLog::NET, "Network not active, %s", pnode->DisconnectMsg()); |
| 1950 | pnode->fDisconnect = true; |
| 1951 | } |
| 1952 | } |
| 1953 | } |
| 1954 | |
| 1955 | // Disconnect unused nodes |
| 1956 | std::vector<CNode*> nodes_copy = m_nodes; |
| 1957 | for (CNode* pnode : nodes_copy) |
| 1958 | { |
| 1959 | if (pnode->fDisconnect) |
| 1960 | { |
| 1961 | // remove from m_nodes |
| 1962 | m_nodes.erase(remove(m_nodes.begin(), m_nodes.end(), pnode), m_nodes.end()); |
| 1963 | |
| 1964 | // Add to reconnection list if appropriate. We don't reconnect right here, because |
| 1965 | // the creation of a connection is a blocking operation (up to several seconds), |
| 1966 | // and we don't want to hold up the socket handler thread for that long. |
| 1967 | if (network_active && pnode->m_transport->ShouldReconnectV1()) { |
| 1968 | reconnections_to_add.push_back({ |
| 1969 | .proxy_override = pnode->m_proxy_override, |
| 1970 | .addr_connect = pnode->addr, |
| 1971 | .grant = std::move(pnode->grantOutbound), |
| 1972 | .destination = pnode->m_dest, |
| 1973 | .conn_type = pnode->m_conn_type, |
| 1974 | .use_v2transport = false}); |
| 1975 | LogDebug(BCLog::NET, "retrying with v1 transport protocol for peer=%d\n", pnode->GetId()); |
| 1976 | } |
| 1977 | |
| 1978 | // release outbound grant (if any) |
| 1979 | pnode->grantOutbound.Release(); |
| 1980 | |
| 1981 | // close socket and cleanup |
| 1982 | pnode->CloseSocketDisconnect(); |
| 1983 | |
| 1984 | // update connection count by network |
| 1985 | if (pnode->IsManualOrFullOutboundConn()) --m_network_conn_counts[pnode->addr.GetNetwork()]; |
| 1986 | |
| 1987 | // hold in disconnected pool until all refs are released |
| 1988 | pnode->Release(); |
| 1989 | m_nodes_disconnected.push_back(pnode); |
nothing calls this directly
no test coverage detected