 |
Bitcoin Core
22.99.0
P2P Digital Currency
|
Go to the documentation of this file.
6 #if defined(HAVE_CONFIG_H)
42 #if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS
55 #include <unordered_map>
88 #define FEELER_SLEEP_WINDOW 1
124 m_addr_fetches.push_back(strDest);
139 int nBestReachability = -1;
142 for (
const auto& entry : mapLocalHost)
144 int nScore = entry.second.nScore;
145 int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
146 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
148 addr =
CService(entry.first, entry.second.nPort);
149 nBestReachability = nReachability;
154 return nBestScore >= 0;
158 static std::vector<CAddress>
ConvertSeeds(
const std::vector<uint8_t> &vSeedsIn)
164 const int64_t nOneWeek = 7*24*60*60;
165 std::vector<CAddress> vSeedsOut;
174 vSeedsOut.push_back(addr);
189 ret =
CAddress(addr, nLocalServices);
198 const auto it = mapLocalHost.find(addr);
199 return (it != mapLocalHost.end()) ? it->second.nScore : 0;
256 if (!addr.IsRoutable())
265 LogPrintf(
"AddLocal(%s,%i)\n", addr.ToString(), nScore);
269 const auto [it, is_newly_added] = mapLocalHost.emplace(addr,
LocalServiceInfo());
271 if (is_newly_added || nScore >= info.
nScore) {
272 info.
nScore = nScore + (is_newly_added ? 0 : 1);
273 info.
nPort = addr.GetPort();
289 mapLocalHost.erase(addr);
297 vfLimited[net] = !reachable;
303 return !vfLimited[net];
315 const auto it = mapLocalHost.find(addr);
316 if (it == mapLocalHost.end())
return false;
326 return mapLocalHost.count(addr) > 0;
332 for (
CNode* pnode : m_nodes) {
333 if (
static_cast<CNetAddr>(pnode->addr) ==
ip) {
343 for (
CNode* pnode : m_nodes) {
354 for (
CNode* pnode : m_nodes) {
355 if (pnode->m_addr_name == addrName) {
365 for (
CNode* pnode : m_nodes) {
366 if (
static_cast<CService>(pnode->addr) == addr) {
381 for (
const CNode* pnode : m_nodes) {
382 if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && pnode->GetLocalNonce() ==
nonce)
392 struct sockaddr_storage sockaddr_bind;
393 socklen_t sockaddr_bind_len =
sizeof(sockaddr_bind);
395 if (!getsockname(sock, (
struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
396 addr_bind.
SetSockAddr((
const struct sockaddr*)&sockaddr_bind);
408 if (pszDest ==
nullptr) {
416 LogPrintf(
"Failed to open new connection, already connected\n");
423 pszDest ? pszDest : addrConnect.
ToString(),
430 std::vector<CService> resolved;
443 LogPrintf(
"Failed to open new connection, already connected\n");
450 bool connected =
false;
451 std::unique_ptr<Sock> sock;
457 bool proxyConnectionFailed =
false;
463 sock = std::move(conn.
sock);
482 if (!proxyConnectionFailed) {
493 uint16_t port{default_port};
495 bool proxyConnectionFailed;
497 proxyConnectionFailed);
516 pszDest ? pszDest :
"",
553 return "outbound-full-relay";
555 return "block-relay-only";
573 if (addrLocal.IsValid()) {
574 error(
"Addr local already set for node: %i. Refusing to change from %s to %s",
id, addrLocal.ToString(), addrLocalIn.
ToString());
576 addrLocal = addrLocalIn;
586 #define X(name) stats.name = name
617 X(mapSendBytesPerMsgCmd);
622 X(mapRecvBytesPerMsgCmd);
646 const auto time = GetTime<std::chrono::microseconds>();
648 m_last_recv = std::chrono::duration_cast<std::chrono::seconds>(time);
649 nRecvBytes += msg_bytes.
size();
650 while (msg_bytes.
size() > 0) {
660 bool reject_message{
false};
662 if (reject_message) {
671 auto i = mapRecvBytesPerMsgCmd.find(msg.
m_type);
672 if (i == mapRecvBytesPerMsgCmd.end()) {
675 assert(i != mapRecvBytesPerMsgCmd.end());
692 unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.
size());
705 catch (
const std::exception&) {
731 unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.
size());
756 reject_message =
false;
773 LogPrint(
BCLog::NET,
"Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n",
778 reject_message =
true;
782 reject_message =
true;
805 auto it =
node.vSendMsg.begin();
806 size_t nSentSize = 0;
808 while (it !=
node.vSendMsg.end()) {
809 const auto& data = *it;
820 node.m_last_send = GetTime<std::chrono::seconds>();
821 node.nSendBytes += nBytes;
822 node.nSendOffset += nBytes;
824 if (
node.nSendOffset == data.size()) {
825 node.nSendOffset = 0;
826 node.nSendSize -= data.size();
839 node.CloseSocketDisconnect();
847 if (it ==
node.vSendMsg.end()) {
851 node.vSendMsg.erase(
node.vSendMsg.begin(), it);
916 template <
typename T,
typename Comparator>
918 std::vector<T>& elements, Comparator comparator,
size_t k,
921 std::sort(elements.begin(), elements.end(), comparator);
922 size_t eraseSize = std::min(k, elements.size());
923 elements.erase(std::remove_if(elements.end() - eraseSize, elements.end(), predicate), elements.end());
934 const size_t initial_size = eviction_candidates.size();
935 const size_t total_protect_size{initial_size / 2};
940 std::array<Net, 3> networks{
944 for (Net& n : networks) {
945 n.count = std::count_if(eviction_candidates.cbegin(), eviction_candidates.cend(),
947 return n.is_local ? c.m_is_local : c.m_network == n.id;
952 std::stable_sort(networks.begin(), networks.end(), [](Net a, Net b) { return a.count < b.count; });
955 const size_t max_protect_by_network{total_protect_size / 2};
956 size_t num_protected{0};
958 while (num_protected < max_protect_by_network) {
960 auto num_networks = std::count_if(networks.begin(), networks.end(), [](
const Net& n) { return n.count; });
961 if (num_networks == 0) {
964 const size_t disadvantaged_to_protect{max_protect_by_network - num_protected};
965 const size_t protect_per_network{std::max(disadvantaged_to_protect / num_networks,
static_cast<size_t>(1))};
967 bool protected_at_least_one{
false};
969 for (Net& n : networks) {
970 if (n.count == 0)
continue;
971 const size_t before = eviction_candidates.size();
974 return n.is_local ? c.m_is_local : c.m_network == n.id;
976 const size_t after = eviction_candidates.size();
977 if (before > after) {
978 protected_at_least_one =
true;
979 const size_t delta{before - after};
980 num_protected += delta;
981 if (num_protected >= max_protect_by_network) {
987 if (!protected_at_least_one) {
994 assert(num_protected == initial_size - eviction_candidates.size());
995 const size_t remaining_to_protect{total_protect_size - num_protected};
999 [[nodiscard]] std::optional<NodeId>
SelectNodeToEvict(std::vector<NodeEvictionCandidate>&& vEvictionCandidates)
1024 if (vEvictionCandidates.empty())
return std::nullopt;
1029 if (std::any_of(vEvictionCandidates.begin(),vEvictionCandidates.end(),[](
NodeEvictionCandidate const &n){return n.prefer_evict;})) {
1030 vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.begin(),vEvictionCandidates.end(),
1036 uint64_t naMostConnections;
1037 unsigned int nMostConnections = 0;
1038 std::chrono::seconds nMostConnectionsTime{0};
1039 std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
1041 std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[
node.nKeyedNetGroup];
1042 group.push_back(
node);
1043 const auto grouptime{group[0].m_connected};
1045 if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
1046 nMostConnections = group.size();
1047 nMostConnectionsTime = grouptime;
1048 naMostConnections =
node.nKeyedNetGroup;
1053 vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1056 return vEvictionCandidates.front().id;
1069 std::vector<NodeEvictionCandidate> vEvictionCandidates;
1076 if (!
node->IsInboundConn())
1078 if (
node->fDisconnect)
1080 bool peer_relay_txes =
false;
1081 bool peer_filter_not_null =
false;
1082 if (
node->m_tx_relay !=
nullptr) {
1084 peer_relay_txes =
node->m_tx_relay->fRelayTxes;
1085 peer_filter_not_null =
node->m_tx_relay->pfilter !=
nullptr;
1088 node->m_last_block_time,
node->m_last_tx_time,
1090 peer_relay_txes, peer_filter_not_null,
node->nKeyedNetGroup,
1091 node->m_prefer_evict,
node->addr.IsLocal(),
1092 node->ConnectedThroughNetwork()};
1093 vEvictionCandidates.push_back(candidate);
1096 const std::optional<NodeId> node_id_to_evict =
SelectNodeToEvict(std::move(vEvictionCandidates));
1097 if (!node_id_to_evict) {
1101 for (
CNode* pnode : m_nodes) {
1102 if (pnode->GetId() == *node_id_to_evict) {
1103 LogPrint(
BCLog::NET,
"selected %s connection for eviction peer=%d; disconnecting\n", pnode->ConnectionTypeAsString(), pnode->GetId());
1104 pnode->fDisconnect =
true;
1112 struct sockaddr_storage sockaddr;
1113 socklen_t len =
sizeof(sockaddr);
1114 auto sock = hListenSocket.
sock->Accept((
struct sockaddr*)&sockaddr, &len);
1125 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr)) {
1126 LogPrintf(
"Warning: Unknown socket family\n");
1158 for (
const CNode* pnode : m_nodes) {
1159 if (pnode->IsInboundConn()) nInbound++;
1170 LogPrintf(
"connection from %s dropped: non-selectable socket\n", addr.
ToString());
1194 if (nInbound >= nMaxInbound)
1198 LogPrint(
BCLog::NET,
"failed to find an eviction candidate - connection dropped (full)\n");
1231 m_nodes.push_back(pnode);
1240 std::optional<int> max_connections;
1241 switch (conn_type) {
1261 return std::count_if(m_nodes.begin(), m_nodes.end(), [conn_type](
CNode*
node) { return node->m_conn_type == conn_type; }););
1264 if (max_connections != std::nullopt && existing_connections >= max_connections)
return false;
1268 if (!grant)
return false;
1281 for (
CNode* pnode : m_nodes) {
1282 if (!pnode->fDisconnect) {
1284 pnode->fDisconnect =
true;
1290 std::vector<CNode*> nodes_copy = m_nodes;
1291 for (
CNode* pnode : nodes_copy)
1293 if (pnode->fDisconnect)
1296 m_nodes.erase(remove(m_nodes.begin(), m_nodes.end(), pnode), m_nodes.end());
1299 pnode->grantOutbound.Release();
1302 pnode->CloseSocketDisconnect();
1313 for (
CNode* pnode : nodes_disconnected_copy)
1316 if (pnode->GetRefCount() <= 0) {
1329 nodes_size = m_nodes.size();
1348 const auto now{GetTime<std::chrono::seconds>()};
1349 const auto last_send{
node.m_last_send.load()};
1350 const auto last_recv{
node.m_last_recv.load()};
1354 if (last_recv.count() == 0 || last_send.count() == 0) {
1369 if (!
node.fSuccessfullyConnected) {
1378 std::set<SOCKET>& recv_set,
1379 std::set<SOCKET>& send_set,
1380 std::set<SOCKET>& error_set)
1383 recv_set.insert(hListenSocket.sock->Get());
1386 for (
CNode* pnode : nodes) {
1398 bool select_recv = !pnode->fPauseRecv;
1401 LOCK(pnode->cs_vSend);
1402 select_send = !pnode->vSendMsg.empty();
1405 LOCK(pnode->m_sock_mutex);
1406 if (!pnode->m_sock) {
1410 error_set.insert(pnode->m_sock->Get());
1412 send_set.insert(pnode->m_sock->Get());
1416 recv_set.insert(pnode->m_sock->Get());
1420 return !recv_set.empty() || !send_set.empty() || !error_set.empty();
1425 std::set<SOCKET>& recv_set,
1426 std::set<SOCKET>& send_set,
1427 std::set<SOCKET>& error_set)
1429 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1430 if (!
GenerateSelectSet(nodes, recv_select_set, send_select_set, error_select_set)) {
1435 std::unordered_map<SOCKET, struct pollfd> pollfds;
1436 for (
SOCKET socket_id : recv_select_set) {
1437 pollfds[socket_id].fd = socket_id;
1438 pollfds[socket_id].events |= POLLIN;
1441 for (
SOCKET socket_id : send_select_set) {
1442 pollfds[socket_id].fd = socket_id;
1443 pollfds[socket_id].events |= POLLOUT;
1446 for (
SOCKET socket_id : error_select_set) {
1447 pollfds[socket_id].fd = socket_id;
1449 pollfds[socket_id].events |= POLLERR|POLLHUP;
1452 std::vector<struct pollfd> vpollfds;
1453 vpollfds.reserve(pollfds.size());
1454 for (
auto it : pollfds) {
1455 vpollfds.push_back(std::move(it.second));
1462 for (
struct pollfd pollfd_entry : vpollfds) {
1463 if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
1464 if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
1465 if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
1470 std::set<SOCKET>& recv_set,
1471 std::set<SOCKET>& send_set,
1472 std::set<SOCKET>& error_set)
1474 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1475 if (!
GenerateSelectSet(nodes, recv_select_set, send_select_set, error_select_set)) {
1483 struct timeval timeout;
1490 FD_ZERO(&fdsetRecv);
1491 FD_ZERO(&fdsetSend);
1492 FD_ZERO(&fdsetError);
1495 for (
SOCKET hSocket : recv_select_set) {
1496 FD_SET(hSocket, &fdsetRecv);
1497 hSocketMax = std::max(hSocketMax, hSocket);
1500 for (
SOCKET hSocket : send_select_set) {
1501 FD_SET(hSocket, &fdsetSend);
1502 hSocketMax = std::max(hSocketMax, hSocket);
1505 for (
SOCKET hSocket : error_select_set) {
1506 FD_SET(hSocket, &fdsetError);
1507 hSocketMax = std::max(hSocketMax, hSocket);
1510 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1519 for (
unsigned int i = 0; i <= hSocketMax; i++)
1520 FD_SET(i, &fdsetRecv);
1521 FD_ZERO(&fdsetSend);
1522 FD_ZERO(&fdsetError);
1527 for (
SOCKET hSocket : recv_select_set) {
1528 if (FD_ISSET(hSocket, &fdsetRecv)) {
1529 recv_set.insert(hSocket);
1533 for (
SOCKET hSocket : send_select_set) {
1534 if (FD_ISSET(hSocket, &fdsetSend)) {
1535 send_set.insert(hSocket);
1539 for (
SOCKET hSocket : error_select_set) {
1540 if (FD_ISSET(hSocket, &fdsetError)) {
1541 error_set.insert(hSocket);
1549 std::set<SOCKET> recv_set;
1550 std::set<SOCKET> send_set;
1551 std::set<SOCKET> error_set;
1560 SocketEvents(snap.Nodes(), recv_set, send_set, error_set);
1571 const std::set<SOCKET>& recv_set,
1572 const std::set<SOCKET>& send_set,
1573 const std::set<SOCKET>& error_set)
1575 for (
CNode* pnode : nodes) {
1582 bool recvSet =
false;
1583 bool sendSet =
false;
1584 bool errorSet =
false;
1586 LOCK(pnode->m_sock_mutex);
1587 if (!pnode->m_sock) {
1590 recvSet = recv_set.count(pnode->m_sock->Get()) > 0;
1591 sendSet = send_set.count(pnode->m_sock->Get()) > 0;
1592 errorSet = error_set.count(pnode->m_sock->Get()) > 0;
1594 if (recvSet || errorSet)
1597 uint8_t pchBuf[0x10000];
1600 LOCK(pnode->m_sock_mutex);
1601 if (!pnode->m_sock) {
1604 nBytes = pnode->m_sock->Recv(pchBuf,
sizeof(pchBuf),
MSG_DONTWAIT);
1608 bool notify =
false;
1609 if (!pnode->ReceiveMsgBytes({pchBuf, (size_t)nBytes}, notify)) {
1610 pnode->CloseSocketDisconnect();
1614 size_t nSizeAdded = 0;
1615 auto it(pnode->vRecvMsg.begin());
1616 for (; it != pnode->vRecvMsg.end(); ++it) {
1619 nSizeAdded += it->m_raw_message_size;
1622 LOCK(pnode->cs_vProcessMsg);
1623 pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
1624 pnode->nProcessQueueSize += nSizeAdded;
1630 else if (nBytes == 0)
1633 if (!pnode->fDisconnect) {
1636 pnode->CloseSocketDisconnect();
1638 else if (nBytes < 0)
1644 if (!pnode->fDisconnect) {
1647 pnode->CloseSocketDisconnect();
1668 if (recv_set.count(listen_socket.sock->Get()) > 0) {
1689 fMsgProcWake =
true;
1699 Shuffle(seeds.begin(), seeds.end(), rng);
1700 int seeds_right_now = 0;
1705 seeds_right_now = seeds.size();
1710 seeds_right_now = seeds.size();
1727 for (
const std::string& seed : seeds) {
1728 if (seeds_right_now == 0) {
1732 LogPrintf(
"Waiting %d seconds before querying DNS seeds.\n", seeds_wait_time.count());
1733 std::chrono::seconds to_wait = seeds_wait_time;
1734 while (to_wait.count() > 0) {
1745 for (
const CNode* pnode : m_nodes) {
1746 if (pnode->fSuccessfullyConnected && pnode->IsFullOutboundConn()) ++nRelevant;
1749 if (nRelevant >= 2) {
1751 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1752 LogPrintf(
"P2P peers available. Finished DNS seeding.\n");
1754 LogPrintf(
"P2P peers available. Skipped DNS seeding.\n");
1766 LogPrintf(
"Waiting for network to be reactivated before querying DNS seeds.\n");
1772 LogPrintf(
"Loading addresses from DNS seed %s\n", seed);
1776 std::vector<CNetAddr> vIPs;
1777 std::vector<CAddress> vAdd;
1779 std::string host =
strprintf(
"x%x.%s", requiredServiceBits, seed);
1784 unsigned int nMaxIPs = 256;
1787 int nOneDay = 24*3600;
1790 vAdd.push_back(addr);
1802 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1817 std::string strDest;
1820 if (m_addr_fetches.empty())
1822 strDest = m_addr_fetches.front();
1823 m_addr_fetches.pop_front();
1840 LogPrint(
BCLog::NET,
"net: setting try another outbound peer=%s\n", flag ?
"true" :
"false");
1851 int full_outbound_peers = 0;
1854 for (
const CNode* pnode : m_nodes) {
1855 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsFullOutboundConn()) {
1856 ++full_outbound_peers;
1865 int block_relay_peers = 0;
1868 for (
const CNode* pnode : m_nodes) {
1869 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsBlockOnlyConn()) {
1870 ++block_relay_peers;
1881 if (!connect.empty())
1883 for (int64_t nLoop = 0;; nLoop++)
1886 for (
const std::string& strAddr : connect)
1890 for (
int i = 0; i < 10 && i < nLoop; i++)
1902 auto start = GetTime<std::chrono::microseconds>();
1910 if (!add_fixed_seeds) {
1911 LogPrintf(
"Fixed seeds are disabled\n");
1930 bool add_fixed_seeds_now =
false;
1932 if (GetTime<std::chrono::seconds>() > start + std::chrono::minutes{1}) {
1933 add_fixed_seeds_now =
true;
1934 LogPrintf(
"Adding fixed seeds as 60 seconds have passed and addrman is empty\n");
1938 if (!add_fixed_seeds_now && !dnsseed) {
1940 if (m_addr_fetches.empty() && m_added_nodes.empty()) {
1941 add_fixed_seeds_now =
true;
1942 LogPrintf(
"Adding fixed seeds as -dnsseed=0, -addnode is not provided and all -seednode(s) attempted\n");
1946 if (add_fixed_seeds_now) {
1950 add_fixed_seeds =
false;
1960 int nOutboundFullRelay = 0;
1961 int nOutboundBlockRelay = 0;
1962 std::set<std::vector<unsigned char> > setConnected;
1966 for (
const CNode* pnode : m_nodes) {
1967 if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
1968 if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
1975 switch (pnode->m_conn_type) {
1989 auto now = GetTime<std::chrono::microseconds>();
1990 bool anchor =
false;
1991 bool fFeeler =
false;
2037 }
else if (now > next_feeler) {
2071 int64_t addr_last_try{0};
2111 if (nANow - addr_last_try < 600 && nTries < 30)
2153 std::vector<CAddress> ret;
2155 for (
const CNode* pnode : m_nodes) {
2156 if (pnode->IsBlockOnlyConn()) {
2157 ret.push_back(pnode->addr);
2166 std::vector<AddedNodeInfo> ret;
2168 std::list<std::string> lAddresses(0);
2171 ret.reserve(m_added_nodes.size());
2172 std::copy(m_added_nodes.cbegin(), m_added_nodes.cend(), std::back_inserter(lAddresses));
2177 std::map<CService, bool> mapConnected;
2178 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
2181 for (
const CNode* pnode : m_nodes) {
2182 if (pnode->addr.IsValid()) {
2183 mapConnected[pnode->addr] = pnode->IsInboundConn();
2185 std::string addrName{pnode->m_addr_name};
2186 if (!addrName.empty()) {
2187 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->IsInboundConn(),
static_cast<const CService&
>(pnode->addr));
2192 for (
const std::string& strAddNode : lAddresses) {
2197 auto it = mapConnected.find(service);
2198 if (it != mapConnected.end()) {
2199 addedNode.resolvedAddress = service;
2200 addedNode.fConnected =
true;
2201 addedNode.fInbound = it->second;
2205 auto it = mapConnectedByName.find(strAddNode);
2206 if (it != mapConnectedByName.end()) {
2207 addedNode.resolvedAddress = it->second.second;
2208 addedNode.fConnected =
true;
2209 addedNode.fInbound = it->second.first;
2212 ret.emplace_back(std::move(addedNode));
2227 if (!info.fConnected) {
2265 }
else if (
FindNode(std::string(pszDest)))
2268 CNode* pnode =
ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
2278 m_nodes.push_back(pnode);
2287 bool fMoreWork =
false;
2295 for (
CNode* pnode : snap.Nodes()) {
2296 if (pnode->fDisconnect)
2301 fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2306 LOCK(pnode->cs_sendProcessing);
2319 fMsgProcWake =
false;
2325 static constexpr
auto err_wait_begin = 1s;
2326 static constexpr
auto err_wait_cap = 5min;
2327 auto err_wait = err_wait_begin;
2329 bool advertising_listen_addr =
false;
2335 if (advertising_listen_addr && conn.
me.
IsValid()) {
2337 advertising_listen_addr =
false;
2341 if (err_wait < err_wait_cap) {
2348 if (!advertising_listen_addr) {
2350 advertising_listen_addr =
true;
2367 struct sockaddr_storage sockaddr;
2368 socklen_t len =
sizeof(sockaddr);
2369 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len))
2376 std::unique_ptr<Sock> sock =
CreateSock(addrBind);
2385 setsockopt(sock->Get(), SOL_SOCKET, SO_REUSEADDR, (
sockopt_arg_type)&nOne,
sizeof(
int));
2391 setsockopt(sock->Get(), IPPROTO_IPV6, IPV6_V6ONLY, (
sockopt_arg_type)&nOne,
sizeof(
int));
2394 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2395 setsockopt(sock->Get(), IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (
const char*)&nProtLevel,
sizeof(
int));
2399 if (::bind(sock->Get(), (
struct sockaddr*)&sockaddr, len) ==
SOCKET_ERROR)
2430 char pszHostName[256] =
"";
2431 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR)
2433 std::vector<CNetAddr> vaddr;
2439 LogPrintf(
"%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2443 #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2445 struct ifaddrs* myaddrs;
2446 if (getifaddrs(&myaddrs) == 0)
2448 for (
struct ifaddrs* ifa = myaddrs; ifa !=
nullptr; ifa = ifa->ifa_next)
2450 if (ifa->ifa_addr ==
nullptr)
continue;
2451 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
2452 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
2453 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
2454 if (ifa->ifa_addr->sa_family == AF_INET)
2456 struct sockaddr_in* s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
2461 else if (ifa->ifa_addr->sa_family == AF_INET6)
2463 struct sockaddr_in6* s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
2469 freeifaddrs(myaddrs);
2476 LogPrintf(
"%s: %s\n", __func__, active);
2490 : addrman(addrman_in), nSeed0(nSeed0In), nSeed1(nSeed1In)
2501 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2529 bool fBound =
false;
2530 for (
const auto& addrBind : options.
vBinds) {
2533 for (
const auto& addrBind : options.
vWhiteBinds) {
2536 for (
const auto& addr_bind : options.
onion_binds) {
2540 struct in_addr inaddr_any;
2541 inaddr_any.s_addr = htonl(INADDR_ANY);
2542 struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2556 _(
"Failed to listen on any port. Use -listen=0 if you want this."),
2568 for (
const auto& strDest : connOptions.
vSeedNodes) {
2578 LogPrintf(
"%i block-relay-only anchors will be tried for connections.\n",
m_anchors.size());
2606 fMsgProcWake =
false;
2623 _(
"Cannot provide specific connections and have addrman find outgoing connections at the same."),
2721 std::vector<CNode*> nodes;
2723 for (
CNode* pnode : nodes) {
2724 pnode->CloseSocketDisconnect();
2752 std::vector<CAddress> addresses =
addrman.
GetAddr(max_addresses, max_pct, network);
2754 addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
2755 [
this](
const CAddress& addr){return m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr);}),
2766 .
Write(local_socket_bytes.data(), local_socket_bytes.size())
2768 const auto current_time = GetTime<std::chrono::microseconds>();
2805 for (
const std::string& it : m_added_nodes) {
2806 if (strNode == it)
return false;
2809 m_added_nodes.push_back(strNode);
2816 for(std::vector<std::string>::iterator it = m_added_nodes.begin(); it != m_added_nodes.end(); ++it) {
2817 if (strNode == *it) {
2818 m_added_nodes.erase(it);
2829 return m_nodes.size();
2832 for (
const auto& pnode : m_nodes) {
2845 vstats.reserve(m_nodes.size());
2846 for (
CNode* pnode : m_nodes) {
2847 vstats.emplace_back();
2848 pnode->CopyStats(vstats.back());
2849 vstats.back().m_mapped_as = pnode->addr.GetMappedAS(
addrman.
GetAsmap());
2858 pnode->fDisconnect =
true;
2866 bool disconnected =
false;
2868 for (
CNode* pnode : m_nodes) {
2869 if (subnet.
Match(pnode->addr)) {
2871 pnode->fDisconnect =
true;
2872 disconnected =
true;
2875 return disconnected;
2886 for(
CNode* pnode : m_nodes) {
2887 if (
id == pnode->GetId()) {
2889 pnode->fDisconnect =
true;
2904 nTotalBytesSent += bytes;
2906 const auto now = GetTime<std::chrono::seconds>();
2910 nMaxOutboundCycleStartTime = now;
2911 nMaxOutboundTotalBytesSentInCycle = 0;
2914 nMaxOutboundTotalBytesSentInCycle += bytes;
2920 return nMaxOutboundLimit;
2931 if (nMaxOutboundLimit == 0)
2934 if (nMaxOutboundCycleStartTime.count() == 0)
2938 const auto now = GetTime<std::chrono::seconds>();
2939 return (cycleEndTime < now) ? 0s : cycleEndTime - now;
2945 if (nMaxOutboundLimit == 0)
2948 if (historicalBlockServingLimit)
2953 if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
2956 else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
2965 if (nMaxOutboundLimit == 0)
2968 return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
2979 return nTotalBytesSent;
2991 m_connected{GetTime<std::chrono::seconds>()},
2993 addrBind(addrBindIn),
2994 m_addr_name{addrNameIn.empty() ? addr.ToStringIPPort() : addrNameIn},
2995 m_inbound_onion(inbound_onion),
2996 nKeyedNetGroup(nKeyedNetGroupIn),
2998 nLocalHostNonce(nLocalHostNonceIn),
2999 m_conn_type(conn_type_in),
3000 nLocalServices(nLocalServicesIn)
3004 m_tx_relay = std::make_unique<TxRelay>();
3008 mapRecvBytesPerMsgCmd[msg] = 0;
3028 size_t nMessageSize = msg.data.size();
3034 TRACE6(net, outbound_message,
3044 std::vector<unsigned char> serializedHeader;
3045 pnode->
m_serializer->prepareForTransport(msg, serializedHeader);
3046 size_t nTotalSize = nMessageSize + serializedHeader.size();
3048 size_t nBytesSent = 0;
3051 bool optimisticSend(pnode->vSendMsg.empty());
3054 pnode->mapSendBytesPerMsgCmd[msg.m_type] += nTotalSize;
3055 pnode->nSendSize += nTotalSize;
3058 pnode->vSendMsg.push_back(std::move(serializedHeader));
3059 if (nMessageSize) pnode->vSendMsg.push_back(std::move(msg.data));
3069 CNode* found =
nullptr;
3071 for (
auto&& pnode : m_nodes) {
3072 if(pnode->
GetId() ==
id) {
3098 auto now = GetTime<std::chrono::microseconds>();
3101 std::string clean_addr = addr.
ToString();
3102 std::replace(clean_addr.begin(), clean_addr.end(),
':',
'_');
3107 fs::path path = base_path / (is_incoming ?
"msgs_recv.dat" :
"msgs_sent.dat");
3115 uint32_t size = data.
size();
static constexpr int ADDRV2_FORMAT
A flag that is ORed into the protocol version to designate that addresses should be serialized in (un...
void SetTryNewOutboundPeer(bool flag)
bool DisconnectNode(const std::string &node)
A combination of a network address (CNetAddr) and a (TCP) port.
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
Span< const std::byte > MakeByteSpan(V &&v) noexcept
static bool CompareNodeBlockRelayOnlyTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
std::vector< CAddress > m_anchors
Addresses that were saved during the previous clean shutdown.
@ INITIALIZATION_DNS_SEED
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
Simple class for background tasks that should be run periodically or once "after a while".
std::vector< std::string > vSeedNodes
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
Resolve a host string to its corresponding network addresses.
std::vector< ListenSocket > vhListenSocket
bool Complete() const override
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
bool IsBanned(const CNetAddr &net_addr)
Return whether net_addr is banned.
bilingual_str _(const char *psz)
Translation function.
static const uint64_t SELECT_TIMEOUT_MILLISECONDS
static int GetnScore(const CService &addr)
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
void ThreadMessageHandler()
std::vector< unsigned char > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
static uint32_t ReadLE32(const unsigned char *ptr)
void RemoveLocal(const CService &addr)
std::chrono::microseconds m_min_ping_time
bool IsDiscouraged(const CNetAddr &net_addr)
Return whether net_addr is discouraged.
unsigned int nSendBufferMaxSize
std::atomic< std::chrono::seconds > m_last_tx_time
UNIX epoch time of the last transaction received from this peer that we had not yet seen (e....
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
static constexpr std::chrono::minutes TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
std::condition_variable condMsgProc
unsigned int nReceiveFloodSize
bool operator()(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) const
void TraceThread(const char *thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.
CHash256 & Write(Span< const unsigned char > input)
bool sleep_for(std::chrono::milliseconds rel_time)
FILE * fopen(const fs::path &p, const char *mode)
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
std::chrono::seconds m_last_block_time
void ThreadDNSAddressSeed()
std::vector< unsigned char > GetAddrBytes() const
std::vector< CService > vBinds
std::vector< unsigned char > data
Mutex g_maplocalhost_mutex
Network GetNetClass() const
void RecordBytesRecv(uint64_t bytes)
std::chrono::seconds GetMaxOutboundTimeframe() const
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
void WakeMessageHandler()
std::atomic< bool > m_bip152_highbandwidth_from
bool Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions)
bool m_i2p_accept_incoming
const std::string NET_MESSAGE_COMMAND_OTHER
std::chrono::seconds m_last_tx_time
int m_max_outbound_full_relay
std::list< CNode * > m_nodes_disconnected
void ser_writedata64(Stream &s, uint64_t obj)
std::vector< CService > m_onion_binds
A vector of -bind=<address>:<port>=onion arguments each of which is an address and port that are desi...
void DumpAnchors(const fs::path &anchors_db_path, const std::vector< CAddress > &anchors)
Dump the anchor IP address database (anchors.dat)
bool OutboundTargetReached(bool historicalBlockServingLimit) const
check if the outbound target is reached if param historicalBlockServingLimit is set true,...
@ NET_MAX
Dummy value to indicate the number of NET_* constants.
@ OUTBOUND_FULL_RELAY
These are the default connections that we use to connect with the network.
Information about a peer.
bool bind_on_any
True if the user did not specify -bind= or -whitebind= and thus we should bind on 0....
void MoveTo(CSemaphoreGrant &grant)
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
Stochastic address manager.
std::atomic< std::chrono::seconds > m_last_block_time
UNIX epoch time of the last block received from this peer that we had not yet seen (e....
void CreateNodeFromAcceptedSocket(std::unique_ptr< Sock > &&sock, NetPermissionFlags permissionFlags, const CAddress &addr_bind, const CAddress &addr)
Create a CNode object from a socket that has just been accepted and add the node to the m_nodes membe...
bool AddConnection(const std::string &address, ConnectionType conn_type)
Attempts to open a connection.
bool SeenLocal(const CService &addr)
vote for a local address
std::unique_ptr< TransportSerializer > m_serializer
static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
size_t size() const
Return the number of (unique) addresses in all tables.
void AcceptConnection(const ListenSocket &hListenSocket)
int64_t GetTime()
DEPRECATED Use either GetTimeSeconds (not mockable) or GetTime<T> (mockable)
CNode(NodeId id, ServiceFlags nLocalServicesIn, std::shared_ptr< Sock > sock, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn, ConnectionType conn_type_in, bool inbound_onion)
bool GetNameProxy(proxyType &nameProxyOut)
static void ClearFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ClearFlag is only called with f == NetPermissionFlags::Implicit.
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection.
std::string ToString() const
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define FEELER_SLEEP_WINDOW
static bool HasFlag(NetPermissionFlags flags, NetPermissionFlags f)
RecursiveMutex cs_totalBytesSent
bool ConnectSocketDirectly(const CService &addrConnect, const Sock &sock, int nTimeout, bool manual_connection)
Try to connect to the specified service on the specified socket.
ServiceFlags
nServices flags
std::vector< CAddress > m_addrs_response_cache
ServiceFlags nServices
Serialized as uint64_t in V1, and as CompactSize in V2.
std::function< std::unique_ptr< Sock >const CService &)> CreateSock
Socket factory.
NetPermissionFlags m_permissionFlags
std::atomic< int64_t > nTimeOffset
std::atomic< ServiceFlags > nServices
const std::chrono::seconds m_connected
Unix epoch time at peer connection.
void SocketEvents(const std::vector< CNode * > &nodes, std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
Check which sockets are ready for IO.
#define WSAGetLastError()
bool Start(CScheduler &scheduler, const Options &options)
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
int readData(Span< const uint8_t > msg_bytes)
uint32_t nTime
Always included in serialization.
bool GetTryNewOutboundPeer() const
static constexpr bool DEFAULT_FORCEDNSSEED
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB.
void NotifyNumConnectionsChanged()
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services),...
std::atomic_bool fDisconnect
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
std::string ToStringIPPort() const
bool Match(const CNetAddr &addr) const
static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD
std::chrono::seconds GetMaxOutboundTimeLeftInCycle() const
returns the time left in the current max outbound cycle in case of no limit, it will always return 0
CService GetAddrLocal() const LOCKS_EXCLUDED(m_addr_local_mutex)
unsigned int nPrevNodeCount
std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval)
Return a timestamp in the future sampled from an exponential distribution (https://en....
@ MANUAL
We open manual connections to addresses that users explicitly requested via the addnode RPC or the -a...
void AddAddrFetch(const std::string &strDest)
bool InactivityCheck(const CNode &node) const
Return true if the peer is inactive and should be disconnected.
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits)
std::string ToStringIP() const
CClientUIInterface * m_client_interface
static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
void GetNodeStats(std::vector< CNodeStats > &vstats) const
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *strDest, ConnectionType conn_type)
ServiceFlags GetLocalServices() const
constexpr std::size_t size() const noexcept
Non-refcounted RAII wrapper for FILE*.
A Span is an object that can refer to a contiguous sequence of objects.
CNode * FindNode(const CNetAddr &ip)
virtual void InitializeNode(CNode *pnode)=0
Initialize a peer (setup state, queue any initial messages)
@ INBOUND
Inbound connections are those initiated by a peer.
bool GenerateSelectSet(const std::vector< CNode * > &nodes, std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
Generate a collection of sockets to check for IO readiness.
std::map< uint64_t, CachedAddrResponse > m_addr_response_caches
Addr responses stored in different caches per (network, local socket) prevent cross-network node iden...
RAII-style semaphore lock.
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
enum Network GetNetwork() const
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
CConnman(uint64_t seed0, uint64_t seed1, AddrMan &addrman, bool network_active=true)
std::string ToString() const
static constexpr uint64_t MAX_SIZE
The maximum size of a serialized object in bytes or number of elements (for eg vectors) when the size...
int GetRandInt(int nMax) noexcept
std::unique_ptr< TransportDeserializer > m_deserializer
bool Good(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an address record as accessible and attempt to move it to addrman's tried table.
ServiceFlags nLocalServices
Services this instance offers.
void ThreadSocketHandler()
void ThreadOpenAddedConnections()
void SplitHostPort(std::string in, uint16_t &portOut, std::string &hostOut)
bool IsPeerAddrLocalGood(CNode *pnode)
Mutex m_addr_fetches_mutex
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
#define AssertLockNotHeld(cs)
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
std::optional< NodeId > SelectNodeToEvict(std::vector< NodeEvictionCandidate > &&vEvictionCandidates)
Select an inbound peer to evict after filtering out (protecting) peers having distinct,...
Network ConnectedThroughNetwork() const
Get network the peer connected through.
static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
std::vector< NetWhitelistPermissions > vWhitelistedRange
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, int64_t nTimePenalty=0)
Attempt to add one or more addresses to addrman's new table.
static CService ip(uint32_t i)
std::atomic_bool m_start_extra_block_relay_peers
flag for initiating extra block-relay-only peer connections.
bool IsReachable(enum Network net)
bool SetSockAddr(const struct sockaddr *paddr)
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
RAII helper to atomically create a copy of m_nodes and add a reference to each of the nodes.
size_t SocketSendData(CNode &node) const EXCLUSIVE_LOCKS_REQUIRED(node.cs_vSend)
std::atomic< std::chrono::seconds > m_last_recv
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
static bool IsSelectableSocket(const SOCKET &s)
BanMan * m_banman
Pointer to this node's banman.
bool AlreadyConnectedToAddress(const CAddress &addr)
Determine whether we're already connected to a given address, in order to avoid initiating duplicate ...
virtual bool SendMessages(CNode *pnode) EXCLUSIVE_LOCKS_REQUIRED(pnode -> cs_sendProcessing)=0
Send queued protocol messages to a given node.
static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS
How long to delay before querying DNS seeds.
std::thread threadOpenConnections
std::unique_ptr< TxRelay > m_tx_relay
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH
Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable).
Sort eviction candidates by network/localhost and connection uptime.
bool ShouldRunInactivityChecks(const CNode &node, std::chrono::seconds now) const
Return true if we should disconnect the peer for failing an inactivity check.
const ConnectionType m_conn_type
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
std::chrono::microseconds m_time
time of message receipt
std::atomic_bool fSuccessfullyConnected
fSuccessfullyConnected is set to true on receiving VERACK from the peer.
std::vector< CService > onion_binds
Cache responses to addr requests to minimize privacy leak.
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
bool fAddressesInitialized
CompareNodeNetworkTime(bool is_local, Network network)
std::atomic< bool > m_bip152_highbandwidth_to
bool m_use_addrman_outgoing
uint64_t GetTotalBytesRecv() const
void SocketHandlerConnected(const std::vector< CNode * > &nodes, const std::set< SOCKET > &recv_set, const std::set< SOCKET > &send_set, const std::set< SOCKET > &error_set)
Do the read/write for connected sockets that are ready for IO.
static constexpr bool DEFAULT_FIXEDSEEDS
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
void scheduleEvery(Function f, std::chrono::milliseconds delta)
Repeat f until the scheduler is stopped.
void AddSocketPermissionFlags(NetPermissionFlags &flags) const
void Finalize(Span< unsigned char > output)
bool InitBinds(const Options &options)
void SetSyscallSandboxPolicy(SyscallSandboxPolicy syscall_policy)
Force the current thread (and threads created from the current thread) into a restricted-service oper...
void SocketHandlerListening(const std::set< SOCKET > &recv_set)
Accept incoming connections, one from each read-ready listening socket.
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
std::pair< CAddress, int64_t > SelectTriedCollision()
Randomly select an address in the tried table that another address is attempting to evict.
std::thread threadMessageHandler
bool AddLocal(const CService &addr_, int nScore)
#define LogPrint(category,...)
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
@ FEELER
Feeler connections are short-lived connections made to check that a node is alive.
void ser_writedata32(Stream &s, uint32_t obj)
std::chrono::seconds m_peer_connect_timeout
unsigned int GetReceiveFloodSize() const
static void EraseLastKElements(std::vector< T > &elements, Comparator comparator, size_t k, std::function< bool(const NodeEvictionCandidate &)> predicate=[](const NodeEvictionCandidate &n) { return true;})
Sort an array by the specified comparator, then erase the last K elements where predicate is true.
CSemaphoreGrant grantOutbound
uint64_t GetMaxOutboundTarget() const
virtual bool ProcessMessages(CNode *pnode, std::atomic< bool > &interrupt)=0
Process protocol messages received from a given node.
const CMessageHeader::MessageStartChars & MessageStart() const
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
void resize(size_type n, value_type c=value_type{})
Span< const std::byte > AsBytes(Span< T > s) noexcept
const std::vector< std::string > & DNSSeeds() const
Return the list of hostnames to look up for DNS seeds.
std::atomic< NodeId > nLastNodeId
bool RemoveAddedNode(const std::string &node)
RecursiveMutex m_nodes_mutex
void SetAddrLocal(const CService &addrLocalIn) LOCKS_EXCLUDED(m_addr_local_mutex)
May not be called more than once.
int GetExtraFullOutboundCount() const
void InterruptSocks5(bool interrupt)
static constexpr std::chrono::seconds MAX_UPLOAD_TIMEFRAME
The default timeframe for -maxuploadtarget.
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
const char *const ANCHORS_DATABASE_FILENAME
Anchor IP address database file name.
std::thread threadI2PAcceptIncoming
constexpr C * data() const noexcept
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
std::atomic_bool m_try_another_outbound_peer
flag for deciding to connect to an extra outbound peer, in excess of m_max_outbound_full_relay This t...
std::string ConnectionTypeAsString(ConnectionType conn_type)
Convert ConnectionType enum to a string value.
int64_t GetAdjustedTime()
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
const uint256 & GetMessageHash() const
A CService with information about it as peer.
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
void SetNetworkActive(bool active)
static CNetCleanup instance_of_cnetcleanup
static bool NodeFullyConnected(const CNode *pnode)
static const bool DEFAULT_WHITELISTRELAY
Default for -whitelistrelay.
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
bool SetSocketNoDelay(const SOCKET &hSocket)
Set the TCP_NODELAY flag on a socket.
Mutex m_added_nodes_mutex
uint32_t m_message_size
size of the payload
const bool m_inbound_onion
Whether this peer is an inbound onion, i.e. connected via our Tor onion service.
std::optional< CAddress > GetLocalAddrForPeer(CNode *pnode)
Returns a local address that we should advertise to this peer.
static const uint64_t RANDOMIZER_ID_NETGROUP
#define EXCLUSIVE_LOCKS_REQUIRED(...)
std::string ToString() const
std::atomic< std::chrono::seconds > m_last_send
@ ADDR_FETCH
AddrFetch connections are short lived connections used to solicit addresses from peers.
int GetExtraBlockRelayCount() const
virtual void FinalizeNode(const CNode &node)=0
Handle removal of a peer (clear state)
@ NET_ONION
TOR (v2 or v3)
const std::vector< bool > & GetAsmap() const
static bool create_directories(const std::filesystem::path &p)
Create directory (and if necessary its parents), unless the leaf directory already exists or is a sym...
void CloseSocketDisconnect()
std::string ConnectionTypeAsString() const
std::pair< CAddress, int64_t > Select(bool newOnly=false) const
Choose an address to connect to.
Transport protocol agnostic message container.
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
static const uint64_t RANDOMIZER_ID_ADDRCACHE
void SocketHandler()
Check connected and listening sockets for IO readiness and process them accordingly.
static std::vector< CAddress > ConvertSeeds(const std::vector< uint8_t > &vSeedsIn)
Convert the serialized seeds into usable address objects.
static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
std::atomic< std::chrono::microseconds > m_last_ping_time
Last measured round-trip time.
An established connection with another peer.
static constexpr auto FEELER_INTERVAL
Run the feeler connection loop once every 2 minutes.
std::vector< AddedNodeInfo > GetAddedNodeInfo() const
void ProtectEvictionCandidatesByRatio(std::vector< NodeEvictionCandidate > &eviction_candidates)
Protect desirable or disadvantaged inbound peers from eviction by ratio.
void CopyStats(CNodeStats &stats)
const std::string m_addr_name
const CChainParams & Params()
Return the currently selected parameters.
std::atomic< uint64_t > nTotalBytesRecv
static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS
Maximum number of block-relay-only anchor connections.
constexpr int64_t count_seconds(std::chrono::seconds t)
Helper to count the seconds of a duration.
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
const std::vector< std::string > & getAllNetMessageTypes()
std::vector< std::string > m_specified_outgoing
bool AddNode(const std::string &node)
bool IsInboundConn() const
std::list< CNetMessage > vRecvMsg
Double ended buffer combining vector and stream-like interfaces.
CService me
Our I2P address.
std::vector< CAddress > ReadAnchors(const fs::path &anchors_db_path)
Read the anchor IP address database (anchors.dat)
void prepareForTransport(CSerializedNetMsg &msg, std::vector< unsigned char > &header) override
@ BF_DONT_ADVERTISE
Do not call AddLocal() for our special addresses, e.g., for incoming Tor connections,...
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE
std::thread threadOpenAddedConnections
std::chrono::microseconds m_cache_entry_expiration
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
Network m_net
Network to which this address belongs.
std::atomic< std::chrono::microseconds > m_min_ping_time
Lowest measured round-trip time.
@ BLOCK_RELAY
We use block-relay-only connections to help prevent against partition attacks.
#define TRACE6(context, event, a, b, c, d, e, f)
bool ReceiveMsgBytes(Span< const uint8_t > msg_bytes, bool &complete)
Receive bytes from the buffer and deserialize them into messages.
CService LookupNumeric(const std::string &name, uint16_t portDefault, DNSLookupFn dns_lookup_function)
Resolve a service string with a numeric IP to its first corresponding service.
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
void ThreadI2PAcceptIncoming()
static CAddress GetBindAddress(SOCKET sock)
Get the bind address for a socket as CAddress.
static const bool DEFAULT_WHITELISTFORCERELAY
Default for -whitelistforcerelay.
bool error(const char *fmt, const Args &... args)
void ThreadOpenConnections(std::vector< std::string > connect)
std::unique_ptr< CSemaphore > semOutbound
std::atomic< int > nVersion
std::unique_ptr< CSemaphore > semAddnode
bool Lookup(const std::string &name, std::vector< CService > &vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
Resolve a service string to its corresponding service.
uint64_t GetTotalBytesSent() const
std::atomic< bool > flagInterruptMsgProc
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest, uint16_t port, const Sock &sock, int nTimeout, bool &outProxyConnectionFailed)
Connect to a specified destination service through a SOCKS5 proxy by first connecting to the SOCKS5 p...
NetEventsInterface * m_msgproc
std::thread threadDNSAddressSeed
void Init(const Options &connOptions)
static constexpr bool DEFAULT_DNSSEED
const CChainParams & m_chain_params
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::shared_ptr< Sock > sock
std::unique_ptr< i2p::sam::Session > m_i2p_sam_session
I2P SAM session.
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
std::thread threadSocketHandler
bool CheckIncomingNonce(uint64_t nonce)
int m_max_outbound_block_relay
bool IsLocal(const CService &addr)
check whether a given address is potentially local
ConnectionType
Different types of connections to a peer.
static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL
std::atomic_bool fPauseSend
int readHeader(Span< const uint8_t > msg_bytes)
std::chrono::seconds m_connected
bool m_use_addrman_outgoing
void AddWhitelistPermissionFlags(NetPermissionFlags &flags, const CNetAddr &addr) const
std::vector< NetWhitebindPermissions > vWhiteBinds
void write(Span< const std::byte > src)
std::atomic< bool > fNetworkActive
CThreadInterrupt interruptNet
This is signaled when network activity should cease.
CService MaybeFlipIPv6toCJDNS(const CService &service)
If an IPv6 address belongs to the address range used by the CJDNS network and the CJDNS network is re...
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS
size_t GetNodeCount(ConnectionDirection) const
void SetIP(const CNetAddr &ip)
constexpr auto GetRandMillis
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
int64_t GetTimeMillis()
Returns the system time (not mockable)
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct, std::optional< Network > network) const
Return all or many randomly selected addresses, optionally by network.
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
BindFlags
Used to pass flags to the Bind() function.
bool BindListenPort(const CService &bindAddr, bilingual_str &strError, NetPermissionFlags permissions)
bool DumpPeerAddresses(const ArgsManager &args, const AddrMan &addr)
#define WAIT_LOCK(cs, name)
uint32_t m_raw_message_size
used wire size of the message (including header/checksum)
static constexpr auto EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL
Run the extra block-relay-only connection loop once every 5 minutes.
std::unique_ptr< Sock > sock
Connected socket.
void CaptureMessage(const CAddress &addr, const std::string &msg_type, const Span< const unsigned char > &data, bool is_incoming)
Dump binary message to file, with timestamp.
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, std::optional< Network > network) const
Return all or many randomly selected addresses, optionally by network.
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
void RecordBytesSent(uint64_t bytes)
static const int PROTOCOL_VERSION
network protocol versioning
uint64_t GetOutboundTargetBytesLeft() const
response the bytes left in the current max outbound cycle in case of no limit, it will always respons...
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE
Number of DNS seeds to query when the number of connections is low.
CNetMessage GetMessage(std::chrono::microseconds time, bool &reject_message) override
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data It is treated as if this was the little-endian interpretation of ...
std::map< CNetAddr, LocalServiceInfo > mapLocalHost GUARDED_BY(g_maplocalhost_mutex)
void DeleteNode(CNode *pnode)
uint16_t GetDefaultPort() const