6 #if defined(HAVE_CONFIG_H)
36 #include <miniupnpc/miniupnpc.h>
37 #include <miniupnpc/upnpcommands.h>
38 #include <miniupnpc/upnperrors.h>
41 static_assert(MINIUPNPC_API_VERSION >= 10,
"miniUPnPc API version >= 10 assumed");
46 #include <unordered_map>
76 #define FEELER_SLEEP_WINDOW 1
79 #if !defined(MSG_NOSIGNAL)
80 #define MSG_NOSIGNAL 0
84 #if !defined(MSG_DONTWAIT)
85 #define MSG_DONTWAIT 0
123 m_addr_fetches.push_back(strDest);
138 int nBestReachability = -1;
141 for (
const auto& entry : mapLocalHost)
143 int nScore = entry.second.nScore;
144 int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
145 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
147 addr =
CService(entry.first, entry.second.nPort);
148 nBestReachability = nReachability;
153 return nBestScore >= 0;
157 static std::vector<CAddress>
convertSeed6(
const std::vector<SeedSpec6> &vSeedsIn)
163 const int64_t nOneWeek = 7*24*60*60;
164 std::vector<CAddress> vSeedsOut;
165 vSeedsOut.reserve(vSeedsIn.size());
167 for (
const auto& seed_in : vSeedsIn) {
169 memcpy(&ip, seed_in.addr,
sizeof(ip));
172 vSeedsOut.push_back(addr);
187 ret =
CAddress(addr, nLocalServices);
196 if (mapLocalHost.count(addr) == 0)
return 0;
197 return mapLocalHost[addr].nScore;
251 bool fAlready = mapLocalHost.count(addr) > 0;
253 if (!fAlready || nScore >= info.
nScore) {
254 info.
nScore = nScore + (fAlready ? 1 : 0);
271 mapLocalHost.erase(addr);
279 vfLimited[net] = !reachable;
285 return !vfLimited[net];
298 if (mapLocalHost.count(addr) == 0)
300 mapLocalHost[addr].nScore++;
310 return mapLocalHost.count(addr) > 0;
316 for (
CNode* pnode : vNodes) {
317 if (
static_cast<CNetAddr>(pnode->addr) == ip) {
327 for (
CNode* pnode : vNodes) {
338 for (
CNode* pnode : vNodes) {
339 if (pnode->GetAddrName() == addrName) {
349 for (
CNode* pnode : vNodes) {
350 if (
static_cast<CService>(pnode->addr) == addr) {
365 for (
const CNode* pnode : vNodes) {
366 if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && pnode->GetLocalNonce() == nonce)
376 struct sockaddr_storage sockaddr_bind;
377 socklen_t sockaddr_bind_len =
sizeof(sockaddr_bind);
379 if (!getsockname(sock, (
struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
380 addr_bind.
SetSockAddr((
const struct sockaddr*)&sockaddr_bind);
392 if (pszDest ==
nullptr) {
400 LogPrintf(
"Failed to open new connection, already connected\n");
407 pszDest ? pszDest : addrConnect.
ToString(),
413 std::vector<CService> resolved;
429 LogPrintf(
"Failed to open new connection, already connected\n");
436 bool connected =
false;
440 bool proxyConnectionFailed =
false;
456 if (!proxyConnectionFailed) {
467 int port = default_port;
469 bool proxyConnectionFailed;
517 return "outbound-full-relay";
519 return "block-relay-only";
534 if (addrName.empty()) {
535 addrName = addrNameIn;
546 if (addrLocal.IsValid()) {
547 error(
"Addr local already set for node: %i. Refusing to change from %s to %s",
id, addrLocal.ToString(), addrLocalIn.
ToString());
549 addrLocal = addrLocalIn;
559 #define X(name) stats.name = name
596 X(mapRecvBytesPerMsgCmd);
614 std::chrono::microseconds ping_wait{0};
616 ping_wait = GetTime<std::chrono::microseconds>() -
m_ping_start.load();
645 const auto time = GetTime<std::chrono::microseconds>();
647 nLastRecv = std::chrono::duration_cast<std::chrono::seconds>(time).count();
648 nRecvBytes += nBytes;
662 uint32_t out_err_raw_size{0};
673 mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(result->m_command);
674 if (i == mapRecvBytesPerMsgCmd.end())
676 assert(i != mapRecvBytesPerMsgCmd.end());
677 i->second += result->m_raw_message_size;
680 vRecvMsg.push_back(std::move(*result));
693 unsigned int nCopy = std::min(nRemaining, nBytes);
706 catch (
const std::exception&) {
732 unsigned int nCopy = std::min(nRemaining, nBytes);
777 out_err_raw_size = msg->m_raw_message_size;
782 out_err_raw_size = msg->m_raw_message_size;
806 auto it = pnode->vSendMsg.begin();
807 size_t nSentSize = 0;
809 while (
it != pnode->vSendMsg.end()) {
810 const auto &data = *
it;
811 assert(data.size() > pnode->nSendOffset);
814 LOCK(pnode->cs_hSocket);
817 nBytes =
send(pnode->hSocket,
reinterpret_cast<const char*
>(data.data()) + pnode->nSendOffset, data.size() - pnode->nSendOffset,
MSG_NOSIGNAL |
MSG_DONTWAIT);
821 pnode->nSendBytes += nBytes;
822 pnode->nSendOffset += nBytes;
824 if (pnode->nSendOffset == data.size()) {
825 pnode->nSendOffset = 0;
826 pnode->nSendSize -= data.size();
827 pnode->fPauseSend = pnode->nSendSize > nSendBufferMaxSize;
840 pnode->CloseSocketDisconnect();
848 if (
it == pnode->vSendMsg.end()) {
849 assert(pnode->nSendOffset == 0);
850 assert(pnode->nSendSize == 0);
852 pnode->vSendMsg.erase(pnode->vSendMsg.begin(),
it);
918 template<
typename T,
typename Comparator>
921 std::sort(elements.begin(), elements.end(), comparator);
922 size_t eraseSize = std::min(k, elements.size());
923 elements.erase(elements.end() - eraseSize, elements.end());
936 std::vector<NodeEvictionCandidate> vEvictionCandidates;
940 for (
const CNode* node : vNodes) {
943 if (!node->IsInboundConn())
945 if (node->fDisconnect)
947 bool peer_relay_txes =
false;
948 bool peer_filter_not_null =
false;
949 if (node->m_tx_relay !=
nullptr) {
950 LOCK(node->m_tx_relay->cs_filter);
951 peer_relay_txes = node->m_tx_relay->fRelayTxes;
952 peer_filter_not_null = node->m_tx_relay->pfilter !=
nullptr;
955 node->nLastBlockTime, node->nLastTXTime,
957 peer_relay_txes, peer_filter_not_null, node->nKeyedNetGroup,
958 node->m_prefer_evict, node->addr.IsLocal()};
959 vEvictionCandidates.push_back(candidate);
976 size_t erase_size = std::min(
size_t(8), vEvictionCandidates.size());
977 vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.end() - erase_size, vEvictionCandidates.end(), [](
NodeEvictionCandidate const &n) { return !n.fRelayTxes && n.fRelevantServices; }), vEvictionCandidates.end());
988 size_t initial_size = vEvictionCandidates.size();
989 size_t total_protect_size = initial_size / 2;
993 size_t local_erase_size = total_protect_size / 2;
994 vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.end() - local_erase_size, vEvictionCandidates.end(), [](
NodeEvictionCandidate const &n) { return n.m_is_local; }), vEvictionCandidates.end());
997 total_protect_size -= initial_size - vEvictionCandidates.size();
1000 if (vEvictionCandidates.empty())
return false;
1005 if (std::any_of(vEvictionCandidates.begin(),vEvictionCandidates.end(),[](
NodeEvictionCandidate const &n){return n.prefer_evict;})) {
1006 vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.begin(),vEvictionCandidates.end(),
1012 uint64_t naMostConnections;
1013 unsigned int nMostConnections = 0;
1014 int64_t nMostConnectionsTime = 0;
1015 std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
1017 std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
1018 group.push_back(node);
1019 int64_t grouptime = group[0].nTimeConnected;
1021 if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
1022 nMostConnections = group.size();
1023 nMostConnectionsTime = grouptime;
1024 naMostConnections = node.nKeyedNetGroup;
1029 vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1032 NodeId evicted = vEvictionCandidates.front().id;
1034 for (
CNode* pnode : vNodes) {
1035 if (pnode->GetId() == evicted) {
1036 pnode->fDisconnect =
true;
1044 struct sockaddr_storage sockaddr;
1045 socklen_t len =
sizeof(sockaddr);
1046 SOCKET hSocket = accept(hListenSocket.
socket, (
struct sockaddr*)&sockaddr, &len);
1052 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr)) {
1053 LogPrintf(
"Warning: Unknown socket family\n");
1060 bool legacyWhitelisted =
false;
1067 legacyWhitelisted =
true;
1072 for (
const CNode* pnode : vNodes) {
1073 if (pnode->IsInboundConn()) nInbound++;
1086 LogPrintf(
"connection from %s dropped: not accepting new connections\n", addr.
ToString());
1093 LogPrintf(
"connection from %s dropped: non-selectable socket\n", addr.
ToString());
1120 if (nInbound >= nMaxInbound)
1124 LogPrint(
BCLog::NET,
"failed to find an eviction candidate - connection dropped (full)\n");
1140 CNode* pnode =
new CNode(
id, nodeServices,
GetBestHeight(), hSocket, addr,
CalculateKeyedNetGroup(addr), nonce, addr_bind,
"",
ConnectionType::INBOUND, inbound_onion);
1152 vNodes.push_back(pnode);
1166 for (
CNode* pnode : vNodes) {
1167 if (!pnode->fDisconnect) {
1169 pnode->fDisconnect =
true;
1175 std::vector<CNode*> vNodesCopy = vNodes;
1176 for (
CNode* pnode : vNodesCopy)
1178 if (pnode->fDisconnect)
1181 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1184 pnode->grantOutbound.Release();
1187 pnode->CloseSocketDisconnect();
1198 for (
CNode* pnode : vNodesDisconnectedCopy)
1201 if (pnode->GetRefCount() <= 0) {
1202 bool fDelete =
false;
1204 TRY_LOCK(pnode->cs_vSend, lockSend);
1223 vNodesSize = vNodes.size();
1252 else if (pnode->
nPingNonceSent && pnode->
m_ping_start.load() + std::chrono::seconds{TIMEOUT_INTERVAL} < GetTime<std::chrono::microseconds>())
1268 recv_set.insert(hListenSocket.socket);
1273 for (
CNode* pnode : vNodes)
1286 bool select_recv = !pnode->fPauseRecv;
1289 LOCK(pnode->cs_vSend);
1290 select_send = !pnode->vSendMsg.empty();
1293 LOCK(pnode->cs_hSocket);
1297 error_set.insert(pnode->hSocket);
1299 send_set.insert(pnode->hSocket);
1303 recv_set.insert(pnode->hSocket);
1308 return !recv_set.empty() || !send_set.empty() || !error_set.empty();
1312 void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1314 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1320 std::unordered_map<SOCKET, struct pollfd> pollfds;
1321 for (
SOCKET socket_id : recv_select_set) {
1322 pollfds[socket_id].fd = socket_id;
1323 pollfds[socket_id].events |= POLLIN;
1326 for (
SOCKET socket_id : send_select_set) {
1327 pollfds[socket_id].fd = socket_id;
1328 pollfds[socket_id].events |= POLLOUT;
1331 for (
SOCKET socket_id : error_select_set) {
1332 pollfds[socket_id].fd = socket_id;
1334 pollfds[socket_id].events |= POLLERR|POLLHUP;
1337 std::vector<struct pollfd> vpollfds;
1338 vpollfds.reserve(pollfds.size());
1339 for (
auto it : pollfds) {
1340 vpollfds.push_back(std::move(
it.second));
1347 for (
struct pollfd pollfd_entry : vpollfds) {
1348 if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
1349 if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
1350 if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
1356 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1365 struct timeval timeout;
1372 FD_ZERO(&fdsetRecv);
1373 FD_ZERO(&fdsetSend);
1374 FD_ZERO(&fdsetError);
1377 for (
SOCKET hSocket : recv_select_set) {
1378 FD_SET(hSocket, &fdsetRecv);
1379 hSocketMax = std::max(hSocketMax, hSocket);
1382 for (
SOCKET hSocket : send_select_set) {
1383 FD_SET(hSocket, &fdsetSend);
1384 hSocketMax = std::max(hSocketMax, hSocket);
1387 for (
SOCKET hSocket : error_select_set) {
1388 FD_SET(hSocket, &fdsetError);
1389 hSocketMax = std::max(hSocketMax, hSocket);
1392 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1401 for (
unsigned int i = 0; i <= hSocketMax; i++)
1402 FD_SET(i, &fdsetRecv);
1403 FD_ZERO(&fdsetSend);
1404 FD_ZERO(&fdsetError);
1409 for (
SOCKET hSocket : recv_select_set) {
1410 if (FD_ISSET(hSocket, &fdsetRecv)) {
1411 recv_set.insert(hSocket);
1415 for (
SOCKET hSocket : send_select_set) {
1416 if (FD_ISSET(hSocket, &fdsetSend)) {
1417 send_set.insert(hSocket);
1421 for (
SOCKET hSocket : error_select_set) {
1422 if (FD_ISSET(hSocket, &fdsetError)) {
1423 error_set.insert(hSocket);
1431 std::set<SOCKET> recv_set, send_set, error_set;
1441 if (hListenSocket.socket !=
INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0)
1450 std::vector<CNode*> vNodesCopy;
1453 vNodesCopy = vNodes;
1454 for (
CNode* pnode : vNodesCopy)
1457 for (
CNode* pnode : vNodesCopy)
1465 bool recvSet =
false;
1466 bool sendSet =
false;
1467 bool errorSet =
false;
1469 LOCK(pnode->cs_hSocket);
1472 recvSet = recv_set.count(pnode->hSocket) > 0;
1473 sendSet = send_set.count(pnode->hSocket) > 0;
1474 errorSet = error_set.count(pnode->hSocket) > 0;
1476 if (recvSet || errorSet)
1479 char pchBuf[0x10000];
1482 LOCK(pnode->cs_hSocket);
1485 nBytes = recv(pnode->hSocket, pchBuf,
sizeof(pchBuf),
MSG_DONTWAIT);
1489 bool notify =
false;
1490 if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify))
1491 pnode->CloseSocketDisconnect();
1494 size_t nSizeAdded = 0;
1495 auto it(pnode->vRecvMsg.begin());
1496 for (;
it != pnode->vRecvMsg.end(); ++
it) {
1499 nSizeAdded +=
it->m_raw_message_size;
1502 LOCK(pnode->cs_vProcessMsg);
1503 pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(),
it);
1504 pnode->nProcessQueueSize += nSizeAdded;
1510 else if (nBytes == 0)
1513 if (!pnode->fDisconnect) {
1516 pnode->CloseSocketDisconnect();
1518 else if (nBytes < 0)
1524 if (!pnode->fDisconnect) {
1527 pnode->CloseSocketDisconnect();
1537 LOCK(pnode->cs_vSend);
1548 for (
CNode* pnode : vNodesCopy)
1567 fMsgProcWake =
true;
1579 static std::thread g_upnp_thread;
1580 static void ThreadMapPort()
1583 const char * multicastif =
nullptr;
1584 const char * minissdpdpath =
nullptr;
1585 struct UPNPDev * devlist =
nullptr;
1589 #if MINIUPNPC_API_VERSION < 14
1590 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &
error);
1592 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &
error);
1595 struct UPNPUrls urls;
1596 struct IGDdatas data;
1599 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr,
sizeof(lanaddr));
1603 char externalIPAddress[40];
1604 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1605 if (r != UPNPCOMMAND_SUCCESS) {
1606 LogPrintf(
"UPnP: GetExternalIPAddress() returned %d\n", r);
1608 if (externalIPAddress[0]) {
1610 if (
LookupHost(externalIPAddress, resolved,
false)) {
1615 LogPrintf(
"UPnP: GetExternalIPAddress failed.\n");
1623 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port.c_str(), port.c_str(), lanaddr, strDesc.c_str(),
"TCP", 0,
"0");
1625 if (r != UPNPCOMMAND_SUCCESS) {
1626 LogPrintf(
"AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r));
1628 LogPrintf(
"UPnP Port Mapping successful.\n");
1630 }
while (g_upnp_interrupt.
sleep_for(std::chrono::minutes(20)));
1632 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(),
"TCP", 0);
1633 LogPrintf(
"UPNP_DeletePortMapping() returned: %d\n", r);
1634 freeUPNPDevlist(devlist); devlist =
nullptr;
1635 FreeUPNPUrls(&urls);
1637 LogPrintf(
"No valid UPnP IGDs found\n");
1638 freeUPNPDevlist(devlist); devlist =
nullptr;
1640 FreeUPNPUrls(&urls);
1646 if (!g_upnp_thread.joinable()) {
1647 assert(!g_upnp_interrupt);
1648 g_upnp_thread = std::thread((std::bind(&
TraceThread<
void (*)()>,
"upnp", &ThreadMapPort)));
1654 if(g_upnp_thread.joinable()) {
1661 if(g_upnp_thread.joinable()) {
1662 g_upnp_thread.join();
1663 g_upnp_interrupt.
reset();
1691 Shuffle(seeds.begin(), seeds.end(), rng);
1692 int seeds_right_now = 0;
1697 seeds_right_now = seeds.size();
1702 seeds_right_now = seeds.size();
1719 for (
const std::string& seed : seeds) {
1720 if (seeds_right_now == 0) {
1724 LogPrintf(
"Waiting %d seconds before querying DNS seeds.\n", seeds_wait_time.count());
1725 std::chrono::seconds to_wait = seeds_wait_time;
1726 while (to_wait.count() > 0) {
1737 for (
const CNode* pnode : vNodes) {
1738 if (pnode->fSuccessfullyConnected && pnode->IsOutboundOrBlockRelayConn()) ++nRelevant;
1741 if (nRelevant >= 2) {
1743 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1744 LogPrintf(
"P2P peers available. Finished DNS seeding.\n");
1746 LogPrintf(
"P2P peers available. Skipped DNS seeding.\n");
1758 LogPrintf(
"Waiting for network to be reactivated before querying DNS seeds.\n");
1764 LogPrintf(
"Loading addresses from DNS seed %s\n", seed);
1768 std::vector<CNetAddr> vIPs;
1769 std::vector<CAddress> vAdd;
1771 std::string host =
strprintf(
"x%x.%s", requiredServiceBits, seed);
1776 unsigned int nMaxIPs = 256;
1779 int nOneDay = 24*3600;
1782 vAdd.push_back(addr);
1794 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1810 std::string strDest;
1813 if (m_addr_fetches.empty())
1815 strDest = m_addr_fetches.front();
1816 m_addr_fetches.pop_front();
1833 LogPrint(
BCLog::NET,
"net: setting try another outbound peer=%s\n", flag ?
"true" :
"false");
1847 for (
const CNode* pnode : vNodes) {
1848 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsOutboundOrBlockRelayConn()) {
1859 if (!connect.empty())
1861 for (int64_t nLoop = 0;; nLoop++)
1864 for (
const std::string& strAddr : connect)
1868 for (
int i = 0; i < 10 && i < nLoop; i++)
1900 static bool done =
false;
1902 LogPrintf(
"Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1916 int nOutboundFullRelay = 0;
1917 int nOutboundBlockRelay = 0;
1918 std::set<std::vector<unsigned char> > setConnected;
1922 for (
const CNode* pnode : vNodes) {
1923 if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
1924 if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
1931 switch (pnode->m_conn_type) {
1946 bool anchor =
false;
1947 bool fFeeler =
false;
1968 }
else if (nTime > nNextFeeler) {
2041 if (nANow - addr.
nLastTry < 600 && nTries < 30)
2058 if (addr.
GetPort() !=
Params().GetDefaultPort() && nTries < 50)
2082 std::vector<CAddress> ret;
2084 for (
const CNode* pnode : vNodes) {
2085 if (pnode->IsBlockOnlyConn()) {
2086 ret.push_back(pnode->addr);
2095 std::vector<AddedNodeInfo> ret;
2097 std::list<std::string> lAddresses(0);
2100 ret.reserve(vAddedNodes.size());
2101 std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
2106 std::map<CService, bool> mapConnected;
2107 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
2110 for (
const CNode* pnode : vNodes) {
2111 if (pnode->addr.IsValid()) {
2112 mapConnected[pnode->addr] = pnode->IsInboundConn();
2114 std::string addrName = pnode->GetAddrName();
2115 if (!addrName.empty()) {
2116 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->IsInboundConn(),
static_cast<const CService&
>(pnode->addr));
2121 for (
const std::string& strAddNode : lAddresses) {
2126 auto it = mapConnected.find(service);
2127 if (
it != mapConnected.end()) {
2128 addedNode.resolvedAddress = service;
2129 addedNode.fConnected =
true;
2130 addedNode.fInbound =
it->second;
2134 auto it = mapConnectedByName.find(strAddNode);
2135 if (
it != mapConnectedByName.end()) {
2136 addedNode.resolvedAddress =
it->second.second;
2137 addedNode.fConnected =
true;
2138 addedNode.fInbound =
it->second.first;
2141 ret.emplace_back(std::move(addedNode));
2155 if (!info.fConnected) {
2193 }
else if (
FindNode(std::string(pszDest)))
2196 CNode* pnode =
ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
2206 vNodes.push_back(pnode);
2214 std::vector<CNode*> vNodesCopy;
2217 vNodesCopy = vNodes;
2218 for (
CNode* pnode : vNodesCopy) {
2223 bool fMoreWork =
false;
2225 for (
CNode* pnode : vNodesCopy)
2227 if (pnode->fDisconnect)
2232 fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2237 LOCK(pnode->cs_sendProcessing);
2247 for (
CNode* pnode : vNodesCopy)
2255 fMsgProcWake =
false;
2264 struct sockaddr_storage sockaddr;
2265 socklen_t len =
sizeof(sockaddr);
2266 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len))
2283 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (
sockopt_arg_type)&nOne,
sizeof(
int));
2289 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
sockopt_arg_type)&nOne,
sizeof(
int));
2292 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2293 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (
const char*)&nProtLevel,
sizeof(
int));
2297 if (::bind(hListenSocket, (
struct sockaddr*)&sockaddr, len) ==
SOCKET_ERROR)
2330 char pszHostName[256] =
"";
2331 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR)
2333 std::vector<CNetAddr> vaddr;
2339 LogPrintf(
"%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2343 #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2345 struct ifaddrs* myaddrs;
2346 if (getifaddrs(&myaddrs) == 0)
2348 for (
struct ifaddrs* ifa = myaddrs; ifa !=
nullptr; ifa = ifa->ifa_next)
2350 if (ifa->ifa_addr ==
nullptr)
continue;
2351 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
2352 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
2353 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
2354 if (ifa->ifa_addr->sa_family == AF_INET)
2356 struct sockaddr_in* s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
2361 else if (ifa->ifa_addr->sa_family == AF_INET6)
2363 struct sockaddr_in6* s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
2369 freeifaddrs(myaddrs);
2376 LogPrintf(
"%s: %s\n", __func__, active);
2388 : nSeed0(nSeed0In), nSeed1(nSeed1In)
2399 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2422 const std::vector<CService>& binds,
2423 const std::vector<NetWhitebindPermissions>& whiteBinds,
2424 const std::vector<CService>& onion_binds)
2426 bool fBound =
false;
2427 for (
const auto& addrBind : binds) {
2430 for (
const auto& addrBind : whiteBinds) {
2433 if (binds.empty() && whiteBinds.empty()) {
2434 struct in_addr inaddr_any;
2435 inaddr_any.s_addr = htonl(INADDR_ANY);
2436 struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2441 for (
const auto& addr_bind : onion_binds) {
2454 nTotalBytesRecv = 0;
2458 nTotalBytesSent = 0;
2459 nMaxOutboundTotalBytesSentInCycle = 0;
2460 nMaxOutboundCycleStartTime = 0;
2466 _(
"Failed to listen on any port. Use -listen=0 if you want this."),
2472 for (
const auto& strDest : connOptions.
vSeedNodes) {
2487 LogPrintf(
"Invalid or missing peers.dat; recreating\n");
2498 LogPrintf(
"%i block-relay-only anchors will be tried for connections.\n",
m_anchors.size());
2501 uiInterface.InitMessage(
_(
"Starting network threads...").translated);
2524 fMsgProcWake =
false;
2541 _(
"Cannot provide specific connections and have addrman find outgoing connections at the same."),
2629 for (
CNode* pnode : vNodes)
2630 pnode->CloseSocketDisconnect();
2637 for (
CNode* pnode : vNodes) {
2653 bool fUpdateConnectionTime =
false;
2655 if (fUpdateConnectionTime) {
2679 return addrman.
Add(vAddr, addrFrom, nTimePenalty);
2684 std::vector<CAddress> addresses =
addrman.
GetAddr(max_addresses, max_pct);
2686 addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
2687 [
this](
const CAddress& addr){return m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr);}),
2700 .
Write(local_socket_bytes.data(), local_socket_bytes.size())
2702 const auto current_time = GetTime<std::chrono::microseconds>();
2739 for (
const std::string&
it : vAddedNodes) {
2740 if (strNode ==
it)
return false;
2743 vAddedNodes.push_back(strNode);
2750 for(std::vector<std::string>::iterator
it = vAddedNodes.begin();
it != vAddedNodes.end(); ++
it) {
2751 if (strNode == *
it) {
2752 vAddedNodes.erase(
it);
2763 return vNodes.size();
2766 for (
const auto& pnode : vNodes) {
2779 vstats.reserve(vNodes.size());
2780 for (
CNode* pnode : vNodes) {
2781 vstats.emplace_back();
2790 pnode->fDisconnect =
true;
2798 bool disconnected =
false;
2800 for (
CNode* pnode : vNodes) {
2801 if (subnet.
Match(pnode->addr)) {
2802 pnode->fDisconnect =
true;
2803 disconnected =
true;
2806 return disconnected;
2817 for(
CNode* pnode : vNodes) {
2818 if (
id == pnode->GetId()) {
2819 pnode->fDisconnect =
true;
2829 nTotalBytesRecv += bytes;
2835 nTotalBytesSent += bytes;
2838 if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe <
now)
2841 nMaxOutboundCycleStartTime =
now;
2842 nMaxOutboundTotalBytesSentInCycle = 0;
2846 nMaxOutboundTotalBytesSentInCycle += bytes;
2852 nMaxOutboundLimit = limit;
2858 return nMaxOutboundLimit;
2864 return nMaxOutboundTimeframe;
2870 if (nMaxOutboundLimit == 0)
2873 if (nMaxOutboundCycleStartTime == 0)
2874 return nMaxOutboundTimeframe;
2876 uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe;
2878 return (cycleEndTime <
now) ? 0 : cycleEndTime -
GetTime();
2884 if (nMaxOutboundTimeframe != timeframe)
2888 nMaxOutboundCycleStartTime =
GetTime();
2890 nMaxOutboundTimeframe = timeframe;
2896 if (nMaxOutboundLimit == 0)
2899 if (historicalBlockServingLimit)
2904 if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
2907 else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
2916 if (nMaxOutboundLimit == 0)
2919 return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
2925 return nTotalBytesRecv;
2931 return nTotalBytesSent;
2941 nBestHeight.store(height, std::memory_order_release);
2946 return nBestHeight.load(std::memory_order_acquire);
2951 CNode::CNode(
NodeId idIn,
ServiceFlags nLocalServicesIn,
int nMyStartingHeightIn,
SOCKET hSocketIn,
const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn,
const CAddress& addrBindIn,
const std::string& addrNameIn,
ConnectionType conn_type_in,
bool inbound_onion)
2954 addrBind(addrBindIn),
2955 nKeyedNetGroup(nKeyedNetGroupIn),
2960 nLocalHostNonce(nLocalHostNonceIn),
2961 m_conn_type(conn_type_in),
2962 nLocalServices(nLocalServicesIn),
2963 nMyStartingHeight(nMyStartingHeightIn),
2964 m_inbound_onion(inbound_onion)
2966 hSocket = hSocketIn;
2974 m_addr_known = MakeUnique<CRollingBloomFilter>(5000, 0.001);
2978 mapRecvBytesPerMsgCmd[msg] = 0;
3003 size_t nMessageSize = msg.data.size();
3007 std::vector<unsigned char> serializedHeader;
3008 pnode->
m_serializer->prepareForTransport(msg, serializedHeader);
3009 size_t nTotalSize = nMessageSize + serializedHeader.size();
3011 size_t nBytesSent = 0;
3014 bool optimisticSend(pnode->vSendMsg.empty());
3022 pnode->vSendMsg.push_back(std::move(serializedHeader));
3024 pnode->vSendMsg.push_back(std::move(msg.data));
3027 if (optimisticSend ==
true)
3036 CNode* found =
nullptr;
3038 for (
auto&& pnode : vNodes) {
3039 if(pnode->
GetId() ==
id) {
3060 return now + (int64_t)(log1p(
GetRand(1ULL << 48) * -0.0000000000000035527136788 ) * average_interval_seconds * -1000000.0 + 0.5);
std::vector< CAddress > ReadAnchors(const fs::path &anchors_db_path)
Read the anchor IP address database (anchors.dat)
void DumpAnchors(const fs::path &anchors_db_path, const std::vector< CAddress > &anchors)
Dump the anchor IP address database (anchors.dat)
const CChainParams & Params()
Return the currently selected parameters.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
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.
bool IsDiscouraged(const CNetAddr &net_addr)
Return whether net_addr is discouraged.
Access to the (IP) address database (peers.dat)
bool Write(const CAddrMan &addr)
bool Read(CAddrMan &addr)
Extended statistics about a CAddress.
int64_t nLastTry
last try whatsoever by us (memory only)
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
size_t size() const
Return the number of (unique) addresses in all tables.
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct)
Return a bunch of addresses, selected at random.
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
CAddrInfo SelectTriedCollision()
Randomly select an address in tried that another address is attempting to evict.
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
void SetServices(const CService &addr, ServiceFlags nServices)
std::vector< bool > m_asmap
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
A CService with information about it as peer.
int GetDefaultPort() const
const std::vector< std::string > & DNSSeeds() const
Return the list of hostnames to look up for DNS seeds.
const CMessageHeader::MessageStartChars & MessageStart() const
std::condition_variable condMsgProc
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct)
std::thread threadMessageHandler
void ThreadOpenAddedConnections()
int GetBestHeight() const
bool GetTryNewOutboundPeer()
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
size_t SocketSendData(CNode *pnode) const
bool InitBinds(const std::vector< CService > &binds, const std::vector< NetWhitebindPermissions > &whiteBinds, const std::vector< CService > &onion_binds)
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
void DeleteNode(CNode *pnode)
bool AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
bool AlreadyConnectedToAddress(const CAddress &addr)
Determine whether we're already connected to a given address, in order to avoid initiating duplicate ...
void AddAddrFetch(const std::string &strDest)
ServiceFlags nLocalServices
Services this instance offers.
size_t GetNodeCount(NumConnections num)
int m_max_outbound_block_relay
void SetTryNewOutboundPeer(bool flag)
std::atomic< bool > flagInterruptMsgProc
unsigned int GetReceiveFloodSize() const
std::list< CNode * > vNodesDisconnected
uint64_t GetTotalBytesRecv()
void SetBestHeight(int height)
void SocketEvents(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
CThreadInterrupt interruptNet
std::unique_ptr< CSemaphore > semAddnode
uint64_t GetMaxOutboundTimeframe()
std::atomic< NodeId > nLastNodeId
void SetMaxOutboundTimeframe(uint64_t timeframe)
set the timeframe for the max outbound target
void SetServices(const CService &addr, ServiceFlags nServices)
uint64_t GetOutboundTargetBytesLeft()
response the bytes left in the current max outbound cycle in case of no limit, it will always respons...
void RecordBytesSent(uint64_t bytes)
BanMan * m_banman
Pointer to this node's banman.
std::thread threadDNSAddressSeed
void ThreadOpenConnections(std::vector< std::string > connect)
std::vector< CAddress > m_anchors
Addresses that were saved during the previous clean shutdown.
RecursiveMutex m_addr_fetches_mutex
unsigned int nPrevNodeCount
void NotifyNumConnectionsChanged()
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection.
bool DisconnectNode(const std::string &node)
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::vector< ListenSocket > vhListenSocket
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
CClientUIInterface * clientInterface
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
std::unique_ptr< CSemaphore > semOutbound
std::vector< NetWhitelistPermissions > vWhitelistedRange
void ThreadSocketHandler()
RecursiveMutex cs_totalBytesSent
bool Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions)
std::thread threadOpenConnections
int64_t m_peer_connect_timeout
CNode * FindNode(const CNetAddr &ip)
void Init(const Options &connOptions)
void MarkAddressGood(const CAddress &addr)
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
unsigned int nReceiveFloodSize
CConnman(uint64_t seed0, uint64_t seed1, bool network_active=true)
RecursiveMutex cs_totalBytesRecv
static bool NodeFullyConnected(const CNode *pnode)
std::atomic< int64_t > m_next_send_inv_to_incoming
void SetMaxOutboundTarget(uint64_t limit)
set the max outbound target in bytes
void WakeMessageHandler()
void SetNetworkActive(bool active)
uint64_t GetMaxOutboundTarget()
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *strDest, ConnectionType conn_type)
bool OutboundTargetReached(bool historicalBlockServingLimit)
check if the outbound target is reached if param historicalBlockServingLimit is set true,...
void AddWhitelistPermissionFlags(NetPermissionFlags &flags, const CNetAddr &addr) const
bool Start(CScheduler &scheduler, const Options &options)
bool GenerateSelectSet(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
void ThreadDNSAddressSeed()
void ThreadMessageHandler()
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
bool fAddressesInitialized
uint64_t GetTotalBytesSent()
uint64_t GetMaxOutboundTimeLeftInCycle()
response the time in second left in the current max outbound cycle in case of no limit,...
RecursiveMutex cs_vAddedNodes
std::thread threadOpenAddedConnections
int64_t PoissonNextSendInbound(int64_t now, int average_interval_seconds)
Attempts to obfuscate tx time through exponentially distributed emitting.
void InactivityCheck(CNode *pnode)
std::atomic< int > nBestHeight
bool CheckIncomingNonce(uint64_t nonce)
int m_max_outbound_full_relay
int GetExtraOutboundCount()
void RecordBytesRecv(uint64_t bytes)
std::vector< AddedNodeInfo > GetAddedNodeInfo()
void GetNodeStats(std::vector< CNodeStats > &vstats)
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
unsigned int nSendBufferMaxSize
bool m_use_addrman_outgoing
std::map< uint64_t, CachedAddrResponse > m_addr_response_caches
Addr responses stored in different caches per (network, local socket) prevent cross-network node iden...
NetEventsInterface * m_msgproc
std::atomic< bool > fNetworkActive
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...
bool AddNode(const std::string &node)
std::thread threadSocketHandler
bool RemoveAddedNode(const std::string &node)
void AcceptConnection(const ListenSocket &hListenSocket)
bool BindListenPort(const CService &bindAddr, bilingual_str &strError, NetPermissionFlags permissions)
void resize(size_type n, value_type c=0)
CHash256 & Write(Span< const unsigned char > input)
void Finalize(Span< unsigned char > output)
Network GetNetClass() const
std::string ToStringIP() const
void SetIP(const CNetAddr &ip)
std::vector< unsigned char > GetAddrBytes() const
std::string ToString() const
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
std::vector< unsigned char > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
uint32_t GetMappedAS(const std::vector< bool > &asmap) const
enum Network GetNetwork() const
Information about a peer.
std::atomic< int64_t > nLastSend
std::atomic< int > nVersion
bool IsInboundConn() const
bool IsManualConn() const
std::atomic< int64_t > nTimeOffset
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
std::string ConnectionTypeAsString() const
std::list< CNetMessage > vRecvMsg
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
std::atomic_bool fSuccessfullyConnected
std::atomic< ServiceFlags > nServices
RecursiveMutex cs_addrLocal
CSemaphoreGrant grantOutbound
const int64_t nTimeConnected
std::string GetAddrName() const
mapMsgCmdSize mapSendBytesPerMsgCmd
RecursiveMutex cs_addrName
void CloseSocketDisconnect()
int GetCommonVersion() const
std::unique_ptr< TransportSerializer > m_serializer
std::atomic< int > nStartingHeight
std::unique_ptr< CRollingBloomFilter > m_addr_known
std::atomic_bool fPauseSend
std::unique_ptr< TxRelay > m_tx_relay
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool &complete)
Receive bytes from the buffer and deserialize them into messages.
void copyStats(CNodeStats &stats, const std::vector< bool > &m_asmap)
std::atomic< std::chrono::microseconds > m_ping_start
When the last ping was sent, or 0 if no ping was ever sent.
void MaybeSetAddrName(const std::string &addrNameIn)
Sets the addrName only if it was not previously set.
std::unique_ptr< TransportDeserializer > m_deserializer
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn, ConnectionType conn_type_in, bool inbound_onion=false)
NetPermissionFlags m_permissionFlags
std::atomic< int64_t > nLastRecv
std::atomic< int64_t > nLastTXTime
UNIX epoch time of the last transaction received from this peer that we had not yet seen (e....
std::atomic< int64_t > nMinPingUsecTime
std::atomic< uint64_t > nPingNonceSent
RecursiveMutex cs_hSocket
const ConnectionType m_conn_type
Network ConnectedThroughNetwork() const
Get network the peer connected through.
ServiceFlags GetLocalServices() const
std::atomic< int64_t > nPingUsecTime
const bool m_inbound_onion
Whether this peer connected via our Tor onion service.
std::atomic< int64_t > nLastBlockTime
UNIX epoch time of the last block received from this peer that we had not yet seen (e....
bool RelayAddrsWithConn() const
std::atomic_bool fDisconnect
CService GetAddrLocal() const
std::string m_conn_type_string
Simple class for background tasks that should be run periodically or once "after a while".
void scheduleEvery(Function f, std::chrono::milliseconds delta)
Repeat f until the scheduler is stopped.
RAII-style semaphore lock.
void MoveTo(CSemaphoreGrant &grant)
A combination of a network address (CNetAddr) and a (TCP) port.
std::string ToStringIPPort() const
std::string ToString() const
bool SetSockAddr(const struct sockaddr *paddr)
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
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 ...
bool Match(const CNetAddr &addr) const
bool sleep_for(std::chrono::milliseconds rel_time)
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
virtual void InitializeNode(CNode *pnode)=0
virtual bool SendMessages(CNode *pnode)=0
virtual bool ProcessMessages(CNode *pnode, std::atomic< bool > &interrupt)=0
virtual void FinalizeNode(const CNode &node, bool &update_connection_time)=0
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
static bool HasFlag(const NetPermissionFlags &flags, NetPermissionFlags f)
static void ClearFlag(NetPermissionFlags &flags, NetPermissionFlags f)
A Span is an object that can refer to a contiguous sequence of objects.
const CChainParams & m_chain_params
Optional< CNetMessage > GetMessage(std::chrono::microseconds time, uint32_t &out_err_raw_size) override
const uint256 & GetMessageHash() const
int readHeader(const char *pch, unsigned int nBytes)
int readData(const char *pch, unsigned int nBytes)
bool Complete() const override
void prepareForTransport(CSerializedNetMsg &msg, std::vector< unsigned char > &header) override
std::string FormatFullVersion()
static uint32_t ReadLE32(const unsigned char *ptr)
#define WSAGetLastError()
static bool IsSelectableSocket(const SOCKET &s)
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits)
void * memcpy(void *a, const void *b, size_t c)
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
static void LogPrintf(const char *fmt, const Args &... args)
#define LogPrint(category,...)
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
bool IsPeerAddrLocalGood(CNode *pnode)
void AdvertiseLocal(CNode *pnode)
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE
Number of DNS seeds to query when the number of connections is low.
static void EraseLastKElements(std::vector< T > &elements, Comparator comparator, size_t k)
Sort an array by the specified comparator, then erase the last K elements.
bool IsLocal(const CService &addr)
check whether a given address is potentially local
static const uint64_t RANDOMIZER_ID_NETGROUP
static const uint64_t SELECT_TIMEOUT_MILLISECONDS
static bool CompareNodeBlockRelayOnlyTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
void RemoveLocal(const CService &addr)
BindFlags
Used to pass flags to the Bind() function.
@ BF_DONT_ADVERTISE
Do not call AddLocal() for our special addresses, e.g., for incoming Tor connections,...
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE
static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL
static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD
static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS
Maximum number of block-relay-only anchor connections.
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
RecursiveMutex cs_mapLocalHost
static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
static bool CompareLocalHostTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
static CAddress GetBindAddress(SOCKET sock)
Get the bind address for a socket as CAddress.
static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS
How long to delay before querying DNS seeds.
static const uint64_t RANDOMIZER_ID_ADDRCACHE
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
const std::string NET_MESSAGE_COMMAND_OTHER
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
const char *const ANCHORS_DATABASE_FILENAME
Anchor IP address database file name.
std::map< CNetAddr, LocalServiceInfo > mapLocalHost GUARDED_BY(cs_mapLocalHost)
bool AddLocal(const CService &addr, int nScore)
#define FEELER_SLEEP_WINDOW
int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS
static int GetnScore(const CService &addr)
static std::vector< CAddress > convertSeed6(const std::vector< SeedSpec6 > &vSeedsIn)
Convert the pnSeed6 array into usable address objects.
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
static CNetCleanup instance_of_cnetcleanup
bool IsReachable(enum Network net)
bool SeenLocal(const CService &addr)
vote for a local address
static const bool DEFAULT_BLOCKSONLY
Default for blocks only.
static const bool DEFAULT_WHITELISTFORCERELAY
Default for -whitelistforcerelay.
static const bool DEFAULT_FORCEDNSSEED
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH
Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable).
static const int FEELER_INTERVAL
Run the feeler connection loop once every 2 minutes or 120 seconds.
static const bool DEFAULT_WHITELISTRELAY
Default for -whitelistrelay.
static const int TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
ConnectionType
Different types of connections to a peer.
@ BLOCK_RELAY
We use block-relay-only connections to help prevent against partition attacks.
@ MANUAL
We open manual connections to addresses that users explicitly inputted via the addnode RPC,...
@ OUTBOUND_FULL_RELAY
These are the default connections that we use to connect with the network.
@ FEELER
Feeler connections are short-lived connections made to check that a node is alive.
@ INBOUND
Inbound connections are those initiated by a peer.
@ ADDR_FETCH
AddrFetch connections are short lived connections used to solicit addresses from peers.
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
const std::chrono::seconds now
std::deque< CInv >::iterator it
@ NET_MAX
Dummy value to indicate the number of NET_* constants.
@ NET_ONION
TOR (v2 or v3)
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
bool GetNameProxy(proxyType &nameProxyOut)
std::string GetNetworkName(enum Network net)
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
bool Lookup(const std::string &name, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
Resolve a service string to its corresponding service.
bool SetSocketNoDelay(const SOCKET &hSocket)
Set the TCP_NODELAY flag on a socket.
CService LookupNumeric(const std::string &name, int portDefault)
Resolve a service string with a numeric IP to its first corresponding service.
bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest, int port, const SOCKET &hSocket, int nTimeout, bool &outProxyConnectionFailed)
Connect to a specified destination service through a SOCKS5 proxy by first connecting to the SOCKS5 p...
void InterruptSocks5(bool interrupt)
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup)
Resolve a host string to its corresponding network addresses.
bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET &hSocket, int nTimeout, bool manual_connection)
Try to connect to the specified service on the specified socket.
bool CloseSocket(SOCKET &hSocket)
Close socket and set hSocket to INVALID_SOCKET.
SOCKET CreateSocket(const CService &addrConnect)
Try to create a socket file descriptor with specific properties in the communications domain (address...
static auto & nullopt
Substitute for C++17 std::nullopt.
boost::optional< T > Optional
Substitute for C++17 std::optional.
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
const std::vector< std::string > & getAllNetMessageTypes()
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services),...
ServiceFlags
nServices flags
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB.
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
int GetRandInt(int nMax) noexcept
constexpr auto GetRandMillis
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
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...
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
void SplitHostPort(std::string in, int &portOut, std::string &hostOut)
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
Cache responses to addr requests to minimize privacy leak.
std::chrono::microseconds m_cache_entry_expiration
std::vector< CAddress > m_addrs_response_cache
void AddSocketPermissionFlags(NetPermissionFlags &flags) const
std::vector< NetWhitebindPermissions > vWhiteBinds
std::vector< CService > onion_binds
std::vector< std::string > m_specified_outgoing
std::vector< CService > vBinds
std::vector< std::string > vSeedNodes
bool m_use_addrman_outgoing
std::vector< unsigned char > data
#define WAIT_LOCK(cs, name)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define TRY_LOCK(cs, name)
const fs::path & GetDataDir(bool fNetSpecific)
bool error(const char *fmt, const Args &... args)
void TraceThread(const char *name, Callable func)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
int64_t GetTimeMicros()
Returns the system time (not mockable)
int64_t GetTimeMillis()
Returns the system time (not mockable)
int64_t GetSystemTimeInSeconds()
Returns the system time (not mockable)
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
int64_t count_microseconds(std::chrono::microseconds t)
int64_t GetAdjustedTime()
bilingual_str _(const char *psz)
Translation function.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
CClientUIInterface uiInterface
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
static const int BIP0031_VERSION
BIP 0031, pong message, is enabled for all versions AFTER this one.