6 #if defined(HAVE_CONFIG_H)
31 #if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS
40 #include <miniupnpc/miniupnpc.h>
41 #include <miniupnpc/upnpcommands.h>
42 #include <miniupnpc/upnperrors.h>
45 static_assert(MINIUPNPC_API_VERSION >= 10,
"miniUPnPc API version >= 10 assumed");
50 #include <unordered_map>
80 #define FEELER_SLEEP_WINDOW 1
83 #if !defined(MSG_NOSIGNAL)
84 #define MSG_NOSIGNAL 0
88 #if !defined(MSG_DONTWAIT)
89 #define MSG_DONTWAIT 0
120 std::map<CNetAddr, LocalServiceInfo> mapLocalHost
GUARDED_BY(cs_mapLocalHost);
127 m_addr_fetches.push_back(strDest);
142 int nBestReachability = -1;
144 LOCK(cs_mapLocalHost);
145 for (
const auto& entry : mapLocalHost)
147 int nScore = entry.second.nScore;
148 int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
149 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
151 addr =
CService(entry.first, entry.second.nPort);
152 nBestReachability = nReachability;
157 return nBestScore >= 0;
161 static std::vector<CAddress>
convertSeed6(
const std::vector<SeedSpec6> &vSeedsIn)
167 const int64_t nOneWeek = 7*24*60*60;
168 std::vector<CAddress> vSeedsOut;
169 vSeedsOut.reserve(vSeedsIn.size());
171 for (
const auto& seed_in : vSeedsIn) {
173 memcpy(&ip, seed_in.addr,
sizeof(ip));
176 vSeedsOut.push_back(addr);
191 ret =
CAddress(addr, nLocalServices);
199 LOCK(cs_mapLocalHost);
200 if (mapLocalHost.count(addr) == 0)
return 0;
201 return mapLocalHost[addr].nScore;
254 LOCK(cs_mapLocalHost);
255 bool fAlready = mapLocalHost.count(addr) > 0;
257 if (!fAlready || nScore >= info.
nScore) {
258 info.
nScore = nScore + (fAlready ? 1 : 0);
273 LOCK(cs_mapLocalHost);
275 mapLocalHost.erase(addr);
282 LOCK(cs_mapLocalHost);
283 vfLimited[net] = !reachable;
288 LOCK(cs_mapLocalHost);
289 return !vfLimited[net];
301 LOCK(cs_mapLocalHost);
302 if (mapLocalHost.count(addr) == 0)
304 mapLocalHost[addr].nScore++;
313 LOCK(cs_mapLocalHost);
314 return mapLocalHost.count(addr) > 0;
320 for (
CNode* pnode : vNodes) {
321 if (static_cast<CNetAddr>(pnode->addr) == ip) {
331 for (
CNode* pnode : vNodes) {
332 if (subNet.
Match(static_cast<CNetAddr>(pnode->addr))) {
342 for (
CNode* pnode : vNodes) {
343 if (pnode->GetAddrName() == addrName) {
353 for (
CNode* pnode : vNodes) {
354 if (static_cast<CService>(pnode->addr) == addr) {
369 for (
const CNode* pnode : vNodes) {
370 if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && pnode->GetLocalNonce() == nonce)
380 struct sockaddr_storage sockaddr_bind;
381 socklen_t sockaddr_bind_len =
sizeof(sockaddr_bind);
383 if (!getsockname(sock, (
struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
384 addr_bind.
SetSockAddr((
const struct sockaddr*)&sockaddr_bind);
396 if (pszDest ==
nullptr) {
404 LogPrintf(
"Failed to open new connection, already connected\n");
411 pszDest ? pszDest : addrConnect.
ToString(),
417 std::vector<CService> resolved;
433 LogPrintf(
"Failed to open new connection, already connected\n");
440 bool connected =
false;
444 bool proxyConnectionFailed =
false;
460 if (!proxyConnectionFailed) {
471 int port = default_port;
473 bool proxyConnectionFailed;
521 return "outbound-full-relay";
523 return "block-relay-only";
538 if (addrName.empty()) {
539 addrName = addrNameIn;
550 if (addrLocal.IsValid()) {
551 error(
"Addr local already set for node: %i. Refusing to change from %s to %s",
id, addrLocal.ToString(), addrLocalIn.
ToString());
553 addrLocal = addrLocalIn;
563 #define X(name) stats.name = name
600 X(mapRecvBytesPerMsgCmd);
618 std::chrono::microseconds ping_wait{0};
620 ping_wait = GetTime<std::chrono::microseconds>() -
m_ping_start.load();
649 const auto time = GetTime<std::chrono::microseconds>();
651 nLastRecv = std::chrono::duration_cast<std::chrono::seconds>(time).
count();
652 nRecvBytes += nBytes;
666 uint32_t out_err_raw_size{0};
671 mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER)->second += out_err_raw_size;
677 mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(result->m_command);
678 if (i == mapRecvBytesPerMsgCmd.end())
679 i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
680 assert(i != mapRecvBytesPerMsgCmd.end());
681 i->second += result->m_raw_message_size;
684 vRecvMsg.push_back(std::move(*result));
697 unsigned int nCopy = std::min(nRemaining, nBytes);
710 catch (
const std::exception&) {
736 unsigned int nCopy = std::min(nRemaining, nBytes);
781 out_err_raw_size = msg->m_raw_message_size;
786 out_err_raw_size = msg->m_raw_message_size;
810 auto it = pnode->vSendMsg.begin();
811 size_t nSentSize = 0;
813 while (
it != pnode->vSendMsg.end()) {
814 const auto &data = *
it;
815 assert(data.size() > pnode->nSendOffset);
818 LOCK(pnode->cs_hSocket);
821 nBytes =
send(pnode->hSocket, reinterpret_cast<const char*>(data.data()) + pnode->nSendOffset, data.size() - pnode->nSendOffset,
MSG_NOSIGNAL |
MSG_DONTWAIT);
825 pnode->nSendBytes += nBytes;
826 pnode->nSendOffset += nBytes;
828 if (pnode->nSendOffset == data.size()) {
829 pnode->nSendOffset = 0;
830 pnode->nSendSize -= data.size();
831 pnode->fPauseSend = pnode->nSendSize > nSendBufferMaxSize;
844 pnode->CloseSocketDisconnect();
852 if (
it == pnode->vSendMsg.end()) {
853 assert(pnode->nSendOffset == 0);
854 assert(pnode->nSendSize == 0);
856 pnode->vSendMsg.erase(pnode->vSendMsg.begin(),
it);
922 template<
typename T,
typename Comparator>
925 std::sort(elements.begin(), elements.end(), comparator);
926 size_t eraseSize = std::min(k, elements.size());
927 elements.erase(elements.end() - eraseSize, elements.end());
940 std::vector<NodeEvictionCandidate> vEvictionCandidates;
944 for (
const CNode* node : vNodes) {
947 if (!node->IsInboundConn())
949 if (node->fDisconnect)
951 bool peer_relay_txes =
false;
952 bool peer_filter_not_null =
false;
953 if (node->m_tx_relay !=
nullptr) {
954 LOCK(node->m_tx_relay->cs_filter);
955 peer_relay_txes = node->m_tx_relay->fRelayTxes;
956 peer_filter_not_null = node->m_tx_relay->pfilter !=
nullptr;
959 node->nLastBlockTime, node->nLastTXTime,
961 peer_relay_txes, peer_filter_not_null, node->nKeyedNetGroup,
962 node->m_prefer_evict, node->addr.IsLocal()};
963 vEvictionCandidates.push_back(candidate);
980 size_t erase_size = std::min(
size_t(8), vEvictionCandidates.size());
981 vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.end() - erase_size, vEvictionCandidates.end(), [](
NodeEvictionCandidate const &n) {
return !n.fRelayTxes && n.fRelevantServices; }), vEvictionCandidates.end());
992 size_t initial_size = vEvictionCandidates.size();
993 size_t total_protect_size = initial_size / 2;
997 size_t local_erase_size = total_protect_size / 2;
998 vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.end() - local_erase_size, vEvictionCandidates.end(), [](
NodeEvictionCandidate const &n) {
return n.m_is_local; }), vEvictionCandidates.end());
1001 total_protect_size -= initial_size - vEvictionCandidates.size();
1004 if (vEvictionCandidates.empty())
return false;
1009 if (std::any_of(vEvictionCandidates.begin(),vEvictionCandidates.end(),[](
NodeEvictionCandidate const &n){
return n.prefer_evict;})) {
1010 vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.begin(),vEvictionCandidates.end(),
1016 uint64_t naMostConnections;
1017 unsigned int nMostConnections = 0;
1018 int64_t nMostConnectionsTime = 0;
1019 std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
1021 std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
1022 group.push_back(node);
1023 int64_t grouptime = group[0].nTimeConnected;
1025 if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
1026 nMostConnections = group.size();
1027 nMostConnectionsTime = grouptime;
1028 naMostConnections = node.nKeyedNetGroup;
1033 vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1036 NodeId evicted = vEvictionCandidates.front().id;
1038 for (
CNode* pnode : vNodes) {
1039 if (pnode->GetId() == evicted) {
1040 pnode->fDisconnect =
true;
1048 struct sockaddr_storage sockaddr;
1049 socklen_t len =
sizeof(sockaddr);
1050 SOCKET hSocket = accept(hListenSocket.
socket, (
struct sockaddr*)&sockaddr, &len);
1053 int nMaxInbound = nMaxConnections - m_max_outbound;
1056 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr)) {
1057 LogPrintf(
"Warning: Unknown socket family\n");
1063 AddWhitelistPermissionFlags(permissionFlags, addr);
1064 bool legacyWhitelisted =
false;
1071 legacyWhitelisted =
true;
1076 for (
const CNode* pnode : vNodes) {
1077 if (pnode->IsInboundConn()) nInbound++;
1089 if (!fNetworkActive) {
1090 LogPrintf(
"connection from %s dropped: not accepting new connections\n", addr.
ToString());
1097 LogPrintf(
"connection from %s dropped: non-selectable socket\n", addr.
ToString());
1107 bool banned = m_banman && m_banman->IsBanned(addr);
1116 bool discouraged = m_banman && m_banman->IsDiscouraged(addr);
1124 if (nInbound >= nMaxInbound)
1126 if (!AttemptToEvictConnection()) {
1128 LogPrint(
BCLog::NET,
"failed to find an eviction candidate - connection dropped (full)\n");
1134 NodeId id = GetNewNodeId();
1135 uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(
id).Finalize();
1143 const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
1144 CNode* pnode =
new CNode(
id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind,
"",
ConnectionType::INBOUND, inbound_onion);
1150 m_msgproc->InitializeNode(pnode);
1156 vNodes.push_back(pnode);
1168 if (!fNetworkActive) {
1170 for (
CNode* pnode : vNodes) {
1171 if (!pnode->fDisconnect) {
1173 pnode->fDisconnect =
true;
1179 std::vector<CNode*> vNodesCopy = vNodes;
1180 for (
CNode* pnode : vNodesCopy)
1182 if (pnode->fDisconnect)
1185 vNodes.erase(
remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1188 pnode->grantOutbound.Release();
1191 pnode->CloseSocketDisconnect();
1195 vNodesDisconnected.push_back(pnode);
1201 std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
1202 for (
CNode* pnode : vNodesDisconnectedCopy)
1205 if (pnode->GetRefCount() <= 0) {
1206 bool fDelete =
false;
1208 TRY_LOCK(pnode->cs_vSend, lockSend);
1214 vNodesDisconnected.remove(pnode);
1227 vNodesSize = vNodes.size();
1229 if(vNodesSize != nPrevNodeCount) {
1230 nPrevNodeCount = vNodesSize;
1232 clientInterface->NotifyNumConnectionsChanged(vNodesSize);
1271 for (
const ListenSocket& hListenSocket : vhListenSocket) {
1272 recv_set.insert(hListenSocket.socket);
1277 for (
CNode* pnode : vNodes)
1290 bool select_recv = !pnode->fPauseRecv;
1293 LOCK(pnode->cs_vSend);
1294 select_send = !pnode->vSendMsg.empty();
1297 LOCK(pnode->cs_hSocket);
1301 error_set.insert(pnode->hSocket);
1303 send_set.insert(pnode->hSocket);
1307 recv_set.insert(pnode->hSocket);
1312 return !recv_set.empty() || !send_set.empty() || !error_set.empty();
1316 void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1318 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1319 if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1320 interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1324 std::unordered_map<SOCKET, struct pollfd> pollfds;
1325 for (
SOCKET socket_id : recv_select_set) {
1326 pollfds[socket_id].fd = socket_id;
1327 pollfds[socket_id].events |= POLLIN;
1330 for (
SOCKET socket_id : send_select_set) {
1331 pollfds[socket_id].fd = socket_id;
1332 pollfds[socket_id].events |= POLLOUT;
1335 for (
SOCKET socket_id : error_select_set) {
1336 pollfds[socket_id].fd = socket_id;
1338 pollfds[socket_id].events |= POLLERR|POLLHUP;
1341 std::vector<struct pollfd> vpollfds;
1342 vpollfds.reserve(pollfds.size());
1343 for (
auto it : pollfds) {
1344 vpollfds.push_back(std::move(
it.second));
1349 if (interruptNet)
return;
1351 for (
struct pollfd pollfd_entry : vpollfds) {
1352 if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
1353 if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
1354 if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
1360 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1361 if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1362 interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1369 struct timeval timeout;
1371 timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000;
1376 FD_ZERO(&fdsetRecv);
1377 FD_ZERO(&fdsetSend);
1378 FD_ZERO(&fdsetError);
1381 for (
SOCKET hSocket : recv_select_set) {
1382 FD_SET(hSocket, &fdsetRecv);
1383 hSocketMax = std::max(hSocketMax, hSocket);
1386 for (
SOCKET hSocket : send_select_set) {
1387 FD_SET(hSocket, &fdsetSend);
1388 hSocketMax = std::max(hSocketMax, hSocket);
1391 for (
SOCKET hSocket : error_select_set) {
1392 FD_SET(hSocket, &fdsetError);
1393 hSocketMax = std::max(hSocketMax, hSocket);
1396 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1405 for (
unsigned int i = 0; i <= hSocketMax; i++)
1406 FD_SET(i, &fdsetRecv);
1407 FD_ZERO(&fdsetSend);
1408 FD_ZERO(&fdsetError);
1409 if (!interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS)))
1413 for (
SOCKET hSocket : recv_select_set) {
1414 if (FD_ISSET(hSocket, &fdsetRecv)) {
1415 recv_set.insert(hSocket);
1419 for (
SOCKET hSocket : send_select_set) {
1420 if (FD_ISSET(hSocket, &fdsetSend)) {
1421 send_set.insert(hSocket);
1425 for (
SOCKET hSocket : error_select_set) {
1426 if (FD_ISSET(hSocket, &fdsetError)) {
1427 error_set.insert(hSocket);
1435 std::set<SOCKET> recv_set, send_set, error_set;
1436 SocketEvents(recv_set, send_set, error_set);
1438 if (interruptNet)
return;
1443 for (
const ListenSocket& hListenSocket : vhListenSocket)
1445 if (hListenSocket.socket !=
INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0)
1447 AcceptConnection(hListenSocket);
1454 std::vector<CNode*> vNodesCopy;
1457 vNodesCopy = vNodes;
1458 for (
CNode* pnode : vNodesCopy)
1461 for (
CNode* pnode : vNodesCopy)
1469 bool recvSet =
false;
1470 bool sendSet =
false;
1471 bool errorSet =
false;
1473 LOCK(pnode->cs_hSocket);
1476 recvSet = recv_set.count(pnode->hSocket) > 0;
1477 sendSet = send_set.count(pnode->hSocket) > 0;
1478 errorSet = error_set.count(pnode->hSocket) > 0;
1480 if (recvSet || errorSet)
1483 char pchBuf[0x10000];
1486 LOCK(pnode->cs_hSocket);
1489 nBytes = recv(pnode->hSocket, pchBuf,
sizeof(pchBuf),
MSG_DONTWAIT);
1493 bool notify =
false;
1494 if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify))
1495 pnode->CloseSocketDisconnect();
1496 RecordBytesRecv(nBytes);
1498 size_t nSizeAdded = 0;
1499 auto it(pnode->vRecvMsg.begin());
1500 for (;
it != pnode->vRecvMsg.end(); ++
it) {
1503 nSizeAdded +=
it->m_raw_message_size;
1506 LOCK(pnode->cs_vProcessMsg);
1507 pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(),
it);
1508 pnode->nProcessQueueSize += nSizeAdded;
1509 pnode->fPauseRecv = pnode->nProcessQueueSize > nReceiveFloodSize;
1511 WakeMessageHandler();
1514 else if (nBytes == 0)
1517 if (!pnode->fDisconnect) {
1520 pnode->CloseSocketDisconnect();
1522 else if (nBytes < 0)
1528 if (!pnode->fDisconnect) {
1531 pnode->CloseSocketDisconnect();
1541 LOCK(pnode->cs_vSend);
1542 size_t nBytes = SocketSendData(pnode);
1544 RecordBytesSent(nBytes);
1548 InactivityCheck(pnode);
1552 for (
CNode* pnode : vNodesCopy)
1559 while (!interruptNet)
1571 fMsgProcWake =
true;
1573 condMsgProc.notify_one();
1583 static std::thread g_upnp_thread;
1584 static void ThreadMapPort()
1587 const char * multicastif =
nullptr;
1588 const char * minissdpdpath =
nullptr;
1589 struct UPNPDev * devlist =
nullptr;
1593 #if MINIUPNPC_API_VERSION < 14
1594 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1596 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
1599 struct UPNPUrls urls;
1600 struct IGDdatas data;
1603 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr,
sizeof(lanaddr));
1607 char externalIPAddress[40];
1608 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1609 if (r != UPNPCOMMAND_SUCCESS) {
1610 LogPrintf(
"UPnP: GetExternalIPAddress() returned %d\n", r);
1612 if (externalIPAddress[0]) {
1614 if (
LookupHost(externalIPAddress, resolved,
false)) {
1619 LogPrintf(
"UPnP: GetExternalIPAddress failed.\n");
1627 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port.c_str(), port.c_str(), lanaddr, strDesc.c_str(),
"TCP", 0,
"0");
1629 if (r != UPNPCOMMAND_SUCCESS) {
1630 LogPrintf(
"AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r));
1632 LogPrintf(
"UPnP Port Mapping successful.\n");
1634 }
while (g_upnp_interrupt.
sleep_for(std::chrono::minutes(20)));
1636 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(),
"TCP", 0);
1637 LogPrintf(
"UPNP_DeletePortMapping() returned: %d\n", r);
1638 freeUPNPDevlist(devlist); devlist =
nullptr;
1639 FreeUPNPUrls(&urls);
1641 LogPrintf(
"No valid UPnP IGDs found\n");
1642 freeUPNPDevlist(devlist); devlist =
nullptr;
1644 FreeUPNPUrls(&urls);
1650 if (!g_upnp_thread.joinable()) {
1651 assert(!g_upnp_interrupt);
1652 g_upnp_thread = std::thread((std::bind(&
TraceThread<
void (*)()>,
"upnp", &ThreadMapPort)));
1658 if(g_upnp_thread.joinable()) {
1665 if(g_upnp_thread.joinable()) {
1666 g_upnp_thread.join();
1667 g_upnp_interrupt.
reset();
1695 Shuffle(seeds.begin(), seeds.end(), rng);
1696 int seeds_right_now = 0;
1701 seeds_right_now = seeds.size();
1702 }
else if (addrman.size() == 0) {
1706 seeds_right_now = seeds.size();
1723 for (
const std::string& seed : seeds) {
1724 if (seeds_right_now == 0) {
1727 if (addrman.size() > 0) {
1728 LogPrintf(
"Waiting %d seconds before querying DNS seeds.\n", seeds_wait_time.count());
1729 std::chrono::seconds to_wait = seeds_wait_time;
1730 while (to_wait.count() > 0) {
1735 if (!interruptNet.sleep_for(w))
return;
1741 for (
const CNode* pnode : vNodes) {
1742 if (pnode->fSuccessfullyConnected && pnode->IsOutboundOrBlockRelayConn()) ++nRelevant;
1745 if (nRelevant >= 2) {
1747 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1748 LogPrintf(
"P2P peers available. Finished DNS seeding.\n");
1750 LogPrintf(
"P2P peers available. Skipped DNS seeding.\n");
1758 if (interruptNet)
return;
1761 if (!fNetworkActive) {
1762 LogPrintf(
"Waiting for network to be reactivated before querying DNS seeds.\n");
1764 if (!interruptNet.sleep_for(std::chrono::seconds{1}))
return;
1765 }
while (!fNetworkActive);
1768 LogPrintf(
"Loading addresses from DNS seed %s\n", seed);
1772 std::vector<CNetAddr> vIPs;
1773 std::vector<CAddress> vAdd;
1775 std::string host =
strprintf(
"x%x.%s", requiredServiceBits, seed);
1780 unsigned int nMaxIPs = 256;
1783 int nOneDay = 24*3600;
1786 vAdd.push_back(addr);
1789 addrman.Add(vAdd, resolveSource);
1798 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1814 std::string strDest;
1817 if (m_addr_fetches.empty())
1819 strDest = m_addr_fetches.front();
1820 m_addr_fetches.pop_front();
1837 LogPrint(
BCLog::NET,
"net: setting try another outbound peer=%s\n", flag ?
"true" :
"false");
1851 for (
const CNode* pnode : vNodes) {
1852 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsOutboundOrBlockRelayConn()) {
1863 if (!connect.empty())
1865 for (int64_t nLoop = 0;; nLoop++)
1868 for (
const std::string& strAddr : connect)
1872 for (
int i = 0; i < 10 && i < nLoop; i++)
1904 static bool done =
false;
1906 LogPrintf(
"Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1920 int nOutboundFullRelay = 0;
1921 int nOutboundBlockRelay = 0;
1922 std::set<std::vector<unsigned char> > setConnected;
1926 for (
const CNode* pnode : vNodes) {
1927 if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
1928 if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
1935 switch (pnode->m_conn_type) {
1950 bool anchor =
false;
1951 bool fFeeler =
false;
1972 }
else if (nTime > nNextFeeler) {
2045 if (nANow - addr.
nLastTry < 600 && nTries < 30)
2086 std::vector<CAddress> ret;
2088 for (
const CNode* pnode : vNodes) {
2089 if (pnode->IsBlockOnlyConn()) {
2090 ret.push_back(pnode->addr);
2099 std::vector<AddedNodeInfo> ret;
2101 std::list<std::string> lAddresses(0);
2104 ret.reserve(vAddedNodes.size());
2105 std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
2110 std::map<CService, bool> mapConnected;
2111 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
2114 for (
const CNode* pnode : vNodes) {
2115 if (pnode->addr.IsValid()) {
2116 mapConnected[pnode->addr] = pnode->IsInboundConn();
2118 std::string addrName = pnode->GetAddrName();
2119 if (!addrName.empty()) {
2120 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->IsInboundConn(),
static_cast<const CService&
>(pnode->addr));
2125 for (
const std::string& strAddNode : lAddresses) {
2130 auto it = mapConnected.find(service);
2131 if (
it != mapConnected.end()) {
2132 addedNode.resolvedAddress = service;
2133 addedNode.fConnected =
true;
2134 addedNode.fInbound =
it->second;
2138 auto it = mapConnectedByName.find(strAddNode);
2139 if (
it != mapConnectedByName.end()) {
2140 addedNode.resolvedAddress =
it->second.second;
2141 addedNode.fConnected =
true;
2142 addedNode.fInbound =
it->second.first;
2145 ret.emplace_back(std::move(addedNode));
2159 if (!info.fConnected) {
2197 }
else if (
FindNode(std::string(pszDest)))
2200 CNode* pnode =
ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
2210 vNodes.push_back(pnode);
2218 std::vector<CNode*> vNodesCopy;
2221 vNodesCopy = vNodes;
2222 for (
CNode* pnode : vNodesCopy) {
2227 bool fMoreWork =
false;
2229 for (
CNode* pnode : vNodesCopy)
2231 if (pnode->fDisconnect)
2236 fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2241 LOCK(pnode->cs_sendProcessing);
2251 for (
CNode* pnode : vNodesCopy)
2259 fMsgProcWake =
false;
2268 struct sockaddr_storage sockaddr;
2269 socklen_t len =
sizeof(sockaddr);
2270 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len))
2287 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (
sockopt_arg_type)&nOne,
sizeof(
int));
2293 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
sockopt_arg_type)&nOne,
sizeof(
int));
2296 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2297 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (
const char*)&nProtLevel,
sizeof(
int));
2301 if (::bind(hListenSocket, (
struct sockaddr*)&sockaddr, len) ==
SOCKET_ERROR)
2334 char pszHostName[256] =
"";
2335 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR)
2337 std::vector<CNetAddr> vaddr;
2343 LogPrintf(
"%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2347 #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2349 struct ifaddrs* myaddrs;
2350 if (getifaddrs(&myaddrs) == 0)
2352 for (
struct ifaddrs* ifa = myaddrs; ifa !=
nullptr; ifa = ifa->ifa_next)
2354 if (ifa->ifa_addr ==
nullptr)
continue;
2355 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
2356 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
2357 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
2358 if (ifa->ifa_addr->sa_family == AF_INET)
2360 struct sockaddr_in* s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
2365 else if (ifa->ifa_addr->sa_family == AF_INET6)
2367 struct sockaddr_in6* s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
2373 freeifaddrs(myaddrs);
2380 LogPrintf(
"%s: %s\n", __func__, active);
2392 : nSeed0(nSeed0In), nSeed1(nSeed1In)
2403 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2426 const std::vector<CService>& binds,
2427 const std::vector<NetWhitebindPermissions>& whiteBinds,
2428 const std::vector<CService>& onion_binds)
2430 bool fBound =
false;
2431 for (
const auto& addrBind : binds) {
2434 for (
const auto& addrBind : whiteBinds) {
2437 if (binds.empty() && whiteBinds.empty()) {
2438 struct in_addr inaddr_any;
2439 inaddr_any.s_addr = htonl(INADDR_ANY);
2440 struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2445 for (
const auto& addr_bind : onion_binds) {
2458 nTotalBytesRecv = 0;
2462 nTotalBytesSent = 0;
2463 nMaxOutboundTotalBytesSentInCycle = 0;
2464 nMaxOutboundCycleStartTime = 0;
2470 _(
"Failed to listen on any port. Use -listen=0 if you want this."),
2476 for (
const auto& strDest : connOptions.
vSeedNodes) {
2491 LogPrintf(
"Invalid or missing peers.dat; recreating\n");
2502 LogPrintf(
"%i block-relay-only anchors will be tried for connections.\n",
m_anchors.size());
2505 uiInterface.InitMessage(
_(
"Starting network threads...").translated);
2528 fMsgProcWake =
false;
2545 _(
"Cannot provide specific connections and have addrman find outgoing connections at the same."),
2633 for (
CNode* pnode : vNodes)
2634 pnode->CloseSocketDisconnect();
2641 for (
CNode* pnode : vNodes) {
2648 vNodesDisconnected.clear();
2649 vhListenSocket.clear();
2657 bool fUpdateConnectionTime =
false;
2659 if (fUpdateConnectionTime) {
2683 return addrman.
Add(vAddr, addrFrom, nTimePenalty);
2688 std::vector<CAddress> addresses =
addrman.
GetAddr(max_addresses, max_pct);
2690 addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
2704 .Write(local_socket_bytes.data(), local_socket_bytes.size())
2706 const auto current_time = GetTime<std::chrono::microseconds>();
2743 for (
const std::string&
it : vAddedNodes) {
2744 if (strNode ==
it)
return false;
2747 vAddedNodes.push_back(strNode);
2754 for(std::vector<std::string>::iterator
it = vAddedNodes.begin();
it != vAddedNodes.end(); ++
it) {
2755 if (strNode == *
it) {
2756 vAddedNodes.erase(
it);
2767 return vNodes.size();
2770 for (
const auto& pnode : vNodes) {
2783 vstats.reserve(vNodes.size());
2784 for (
CNode* pnode : vNodes) {
2785 vstats.emplace_back();
2794 pnode->fDisconnect =
true;
2802 bool disconnected =
false;
2804 for (
CNode* pnode : vNodes) {
2805 if (subnet.
Match(pnode->addr)) {
2806 pnode->fDisconnect =
true;
2807 disconnected =
true;
2810 return disconnected;
2821 for(
CNode* pnode : vNodes) {
2822 if (
id == pnode->GetId()) {
2823 pnode->fDisconnect =
true;
2833 nTotalBytesRecv += bytes;
2839 nTotalBytesSent += bytes;
2842 if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe < now)
2845 nMaxOutboundCycleStartTime =
now;
2846 nMaxOutboundTotalBytesSentInCycle = 0;
2850 nMaxOutboundTotalBytesSentInCycle += bytes;
2856 nMaxOutboundLimit = limit;
2862 return nMaxOutboundLimit;
2868 return nMaxOutboundTimeframe;
2874 if (nMaxOutboundLimit == 0)
2877 if (nMaxOutboundCycleStartTime == 0)
2878 return nMaxOutboundTimeframe;
2880 uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe;
2882 return (cycleEndTime < now) ? 0 : cycleEndTime -
GetTime();
2888 if (nMaxOutboundTimeframe != timeframe)
2892 nMaxOutboundCycleStartTime =
GetTime();
2894 nMaxOutboundTimeframe = timeframe;
2900 if (nMaxOutboundLimit == 0)
2903 if (historicalBlockServingLimit)
2908 if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
2911 else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
2920 if (nMaxOutboundLimit == 0)
2923 return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
2929 return nTotalBytesRecv;
2935 return nTotalBytesSent;
2945 nBestHeight.store(height, std::memory_order_release);
2950 return nBestHeight.load(std::memory_order_acquire);
2955 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)
2958 addrBind(addrBindIn),
2959 nKeyedNetGroup(nKeyedNetGroupIn),
2964 nLocalHostNonce(nLocalHostNonceIn),
2965 m_conn_type(conn_type_in),
2966 nLocalServices(nLocalServicesIn),
2967 nMyStartingHeight(nMyStartingHeightIn),
2968 m_inbound_onion(inbound_onion)
2970 hSocket = hSocketIn;
2978 m_addr_known = MakeUnique<CRollingBloomFilter>(5000, 0.001);
2982 mapRecvBytesPerMsgCmd[msg] = 0;
3007 size_t nMessageSize = msg.data.size();
3011 std::vector<unsigned char> serializedHeader;
3012 pnode->
m_serializer->prepareForTransport(msg, serializedHeader);
3013 size_t nTotalSize = nMessageSize + serializedHeader.size();
3015 size_t nBytesSent = 0;
3018 bool optimisticSend(pnode->vSendMsg.empty());
3026 pnode->vSendMsg.push_back(std::move(serializedHeader));
3028 pnode->vSendMsg.push_back(std::move(msg.data));
3031 if (optimisticSend ==
true)
3040 CNode* found =
nullptr;
3042 for (
auto&& pnode : vNodes) {
3043 if(pnode->
GetId() == id) {
3064 return now + (int64_t)(log1p(
GetRand(1ULL << 48) * -0.0000000000000035527136788 ) * average_interval_seconds * -1000000.0 + 0.5);
std::vector< CService > vBinds
std::atomic< bool > flagInterruptMsgProc
void copyStats(CNodeStats &stats, const std::vector< bool > &m_asmap)
std::vector< CAddress > m_addrs_response_cache
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
std::atomic< uint64_t > nPingNonceSent
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
void MoveTo(CSemaphoreGrant &grant)
std::atomic_bool fPauseSend
Access to the (IP) address database (peers.dat)
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
void ThreadOpenAddedConnections()
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
bool sleep_for(std::chrono::milliseconds rel_time)
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH
Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable).
int GetCommonVersion() const
std::deque< CInv >::iterator it
bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET &hSocket, int nTimeout, bool manual_connection)
Try to connect to the specified service on the specified socket.
CService LookupNumeric(const std::string &name, int portDefault)
Resolve a service string with a numeric IP to its first corresponding service.
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
const std::chrono::seconds now
std::atomic< bool > fNetworkActive
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ServiceFlags
nServices flags
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
void Finalize(Span< unsigned char > output)
std::unique_ptr< TransportSerializer > m_serializer
#define LogPrint(category,...)
unsigned int GetReceiveFloodSize() const
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
bool AddLocal(const CService &addr, int nScore)
A set of addresses that represent the hash of a string or FQDN.
We open manual connections to addresses that users explicitly inputted via the addnode RPC...
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 ...
#define TRY_LOCK(cs, name)
Dummy value to indicate the number of NET_* constants.
void scheduleEvery(Function f, std::chrono::milliseconds delta)
Repeat f until the scheduler is stopped.
static bool IsSelectableSocket(const SOCKET &s)
std::atomic< int > nBestHeight
void SetIP(const CNetAddr &ip)
void WakeMessageHandler()
bool Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions)
void SetServices(const CService &addr, ServiceFlags nServices)
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
void SocketEvents(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection. ...
int64_t GetTimeMillis()
Returns the system time (not mockable)
static const bool DEFAULT_FORCEDNSSEED
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool &complete)
Receive bytes from the buffer and deserialize them into messages.
mapMsgCmdSize mapSendBytesPerMsgCmd
std::string ToStringIP() const
int64_t count_microseconds(std::chrono::microseconds t)
const uint256 & GetMessageHash() const
static void ClearFlag(NetPermissionFlags &flags, NetPermissionFlags f)
std::vector< unsigned char > data
static void LogPrintf(const char *fmt, const Args &...args)
const ConnectionType m_conn_type
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
std::vector< NetWhitelistPermissions > vWhitelistedRange
const std::vector< std::string > & DNSSeeds() const
Return the list of hostnames to look up for DNS seeds.
constexpr auto GetRandMillis
int m_max_outbound_full_relay
std::string ToStringIPPort() const
void resize(size_type n, value_type c=0)
bool GetNameProxy(proxyType &nameProxyOut)
uint32_t GetMappedAS(const std::vector< bool > &asmap) const
bool AlreadyConnectedToAddress(const CAddress &addr)
Determine whether we're already connected to a given address, in order to avoid initiating duplicate ...
bool GetTryNewOutboundPeer()
#define FEELER_SLEEP_WINDOW
std::atomic< int64_t > m_next_send_inv_to_incoming
RAII-style semaphore lock.
uint64_t GetMaxOutboundTarget()
static const int BIP0031_VERSION
BIP 0031, pong message, is enabled for all versions AFTER this one.
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
int readHeader(const char *pch, unsigned int nBytes)
bool BindListenPort(const CService &bindAddr, bilingual_str &strError, NetPermissionFlags permissions)
void SetMaxOutboundTimeframe(uint64_t timeframe)
set the timeframe for the max outbound target
RecursiveMutex cs_addrName
CService GetAddrLocal() const
static auto & nullopt
Substitute for C++17 std::nullopt.
NetEventsInterface * m_msgproc
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
static bool CompareLocalHostTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
int m_max_outbound_block_relay
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.
void SetTryNewOutboundPeer(bool flag)
std::unique_ptr< TransportDeserializer > m_deserializer
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE
bool SeenLocal(const CService &addr)
vote for a local address
void ThreadSocketHandler()
static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
static bool CompareNodeBlockRelayOnlyTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
virtual bool SendMessages(CNode *pnode)=0
size_t GetNodeCount(NumConnections num)
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
bool Match(const CNetAddr &addr) const
std::atomic< int > nStartingHeight
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
static const int FEELER_INTERVAL
Run the feeler connection loop once every 2 minutes or 120 seconds.
static const int TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
int64_t GetSystemTimeInSeconds()
Returns the system time (not mockable)
#define WSAGetLastError()
static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
std::list< CNetMessage > vRecvMsg
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
void DumpAnchors(const fs::path &anchors_db_path, const std::vector< CAddress > &anchors)
Dump the anchor IP address database (anchors.dat)
void NotifyNumConnectionsChanged()
void SetMaxOutboundTarget(uint64_t limit)
set the max outbound target in bytes
void RecordBytesSent(uint64_t bytes)
std::map< uint64_t, CachedAddrResponse > m_addr_response_caches
Addr responses stored in different caches per (network, local socket) prevent cross-network node iden...
std::atomic< ServiceFlags > nServices
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
uint64_t GetMaxOutboundTimeframe()
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...
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
ServiceFlags nLocalServices
Services this instance offers.
RecursiveMutex cs_mapLocalHost
bool DisconnectNode(const std::string &node)
bool RelayAddrsWithConn() const
static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD
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.
std::atomic< int64_t > nLastSend
void RecordBytesRecv(uint64_t bytes)
bool IsDiscouraged(const CNetAddr &net_addr)
Return whether net_addr is discouraged.
int readData(const char *pch, unsigned int nBytes)
size_t size() const
Return the number of (unique) addresses in all tables.
std::atomic< int64_t > nPingUsecTime
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
std::atomic< int64_t > nMinPingUsecTime
Extended statistics about a CAddress.
static CAddress GetBindAddress(SOCKET sock)
Get the bind address for a socket as CAddress.
bool error(const char *fmt, const Args &...args)
void CloseSocketDisconnect()
uint64_t GetOutboundTargetBytesLeft()
response the bytes left in the current max outbound cycle in case of no limit, it will always respons...
bool IsInboundConn() const
bool Write(const CAddrMan &addr)
std::chrono::microseconds m_cache_entry_expiration
void AddAddrFetch(const std::string &strDest)
static bool NodeFullyConnected(const CNode *pnode)
std::unique_ptr< CRollingBloomFilter > m_addr_known
static const uint64_t RANDOMIZER_ID_NETGROUP
bool AddNode(const std::string &node)
std::condition_variable condMsgProc
RecursiveMutex cs_vAddedNodes
uint64_t GetMaxOutboundTimeLeftInCycle()
response the time in second left in the current max outbound cycle in case of no limit, it will always response 0
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *strDest, ConnectionType conn_type)
void InactivityCheck(CNode *pnode)
std::atomic< int64_t > nLastRecv
int GetDefaultPort() const
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services)...
std::thread threadOpenAddedConnections
std::vector< CAddress > ReadAnchors(const fs::path &anchors_db_path)
Read the anchor IP address database (anchors.dat)
CNode * FindNode(const CNetAddr &ip)
RecursiveMutex m_addr_fetches_mutex
bilingual_str _(const char *psz)
Translation function.
bool IsPeerAddrLocalGood(CNode *pnode)
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE
Number of DNS seeds to query when the number of connections is low.
A combination of a network address (CNetAddr) and a (TCP) port.
std::vector< std::string > vSeedNodes
int64_t PoissonNextSendInbound(int64_t now, int average_interval_seconds)
Attempts to obfuscate tx time through exponentially distributed emitting.
bool OutboundTargetReached(bool historicalBlockServingLimit)
check if the outbound target is reached if param historicalBlockServingLimit is set true...
std::vector< std::string > m_specified_outgoing
const fs::path & GetDataDir(bool fNetSpecific)
std::unique_ptr< CSemaphore > semOutbound
void ThreadOpenConnections(std::vector< std::string > connect)
std::thread threadMessageHandler
static bool HasFlag(const NetPermissionFlags &flags, NetPermissionFlags f)
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
virtual void FinalizeNode(const CNode &node, bool &update_connection_time)=0
A CService with information about it as peer.
bool Start(CScheduler &scheduler, const Options &options)
static int GetnScore(const CService &addr)
void MaybeSetAddrName(const std::string &addrNameIn)
Sets the addrName only if it was not previously set.
const std::vector< std::string > & getAllNetMessageTypes()
uint64_t GetTotalBytesRecv()
std::string ToString() const
Do not call AddLocal() for our special addresses, e.g., for incoming Tor connections, to prevent gossiping them over the network.
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...
void SetNetworkActive(bool active)
#define WAIT_LOCK(cs, name)
const CMessageHeader::MessageStartChars & MessageStart() const
CClientUIInterface * clientInterface
void GetNodeStats(std::vector< CNodeStats > &vstats)
static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS
const bool m_inbound_onion
Whether this peer connected via our Tor onion service.
bool AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
std::atomic_bool fDisconnect
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
bool InitBinds(const std::vector< CService > &binds, const std::vector< NetWhitebindPermissions > &whiteBinds, const std::vector< CService > &onion_binds)
void TraceThread(const char *name, Callable func)
ServiceFlags GetLocalServices() const
bool CloseSocket(SOCKET &hSocket)
Close socket and set hSocket to INVALID_SOCKET.
void prepareForTransport(CSerializedNetMsg &msg, std::vector< unsigned char > &header) override
static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS
Maximum number of block-relay-only anchor connections.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
std::string FormatFullVersion()
const std::string NET_MESSAGE_COMMAND_OTHER
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB...
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Inbound connections are those initiated by a peer.
void DeleteNode(CNode *pnode)
static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS
How long to delay before querying DNS seeds.
bool CheckIncomingNonce(uint64_t nonce)
static uint32_t ReadLE32(const unsigned char *ptr)
bool Complete() const override
const int64_t nTimeConnected
std::vector< unsigned char > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
int64_t GetTimeMicros()
Returns the system time (not mockable)
std::atomic< NodeId > nLastNodeId
bool RemoveAddedNode(const std::string &node)
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup)
Resolve a host string to its corresponding network addresses.
std::list< CNode * > vNodesDisconnected
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
std::vector< CService > onion_binds
bool IsReachable(enum Network net)
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Optional< CNetMessage > GetMessage(std::chrono::microseconds time, uint32_t &out_err_raw_size) override
#define EXCLUSIVE_LOCKS_REQUIRED(...)
static const bool DEFAULT_WHITELISTFORCERELAY
Default for -whitelistforcerelay.
std::string GetAddrName() const
BanMan * m_banman
Pointer to this node's banman.
std::atomic< int64_t > nLastTXTime
UNIX epoch time of the last transaction received from this peer that we had not yet seen (e...
void AddWhitelistPermissionFlags(NetPermissionFlags &flags, const CNetAddr &addr) const
static const uint64_t SELECT_TIMEOUT_MILLISECONDS
int GetBestHeight() const
std::thread threadOpenConnections
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
ConnectionType
Different types of connections to a peer.
static std::vector< CAddress > convertSeed6(const std::vector< SeedSpec6 > &vSeedsIn)
Convert the pnSeed6 array into usable address objects.
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)
const CChainParams & Params()
Return the currently selected parameters.
CSemaphoreGrant grantOutbound
bool SetSocketNoDelay(const SOCKET &hSocket)
Set the TCP_NODELAY flag on a socket.
const CChainParams & m_chain_params
void * memcpy(void *a, const void *b, size_t c)
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Feeler connections are short-lived connections made to check that a node is alive.
NetPermissionFlags m_permissionFlags
bool fAddressesInitialized
std::thread threadDNSAddressSeed
int64_t GetAdjustedTime()
CAddrInfo SelectTriedCollision()
Randomly select an address in tried that another address is attempting to evict.
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
std::vector< ListenSocket > vhListenSocket
std::string ConnectionTypeAsString() const
void SetBestHeight(int height)
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
SOCKET CreateSocket(const CService &addrConnect)
Try to create a socket file descriptor with specific properties in the communications domain (address...
static const uint64_t RANDOMIZER_ID_ADDRCACHE
Network GetNetClass() const
std::atomic< int64_t > nTimeOffset
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct)
Return a bunch of addresses, selected at random.
int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
std::atomic_bool fSuccessfullyConnected
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 m_conn_type_string
void ThreadMessageHandler()
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct)
These are the default connections that we use to connect with the network.
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions...
std::atomic< int > nVersion
void InterruptSocks5(bool interrupt)
unsigned int nSendBufferMaxSize
static const bool DEFAULT_BLOCKSONLY
Default for blocks only.
static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL
std::vector< bool > m_asmap
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits) ...
int GetExtraOutboundCount()
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
Network ConnectedThroughNetwork() const
Get network the peer connected through.
static const bool DEFAULT_WHITELISTRELAY
Default for -whitelistrelay.
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
bool IsBanned(const CNetAddr &net_addr)
Return whether net_addr is banned.
std::string ToString() const
BindFlags
Used to pass flags to the Bind() function.
void SetServices(const CService &addr, ServiceFlags nServices)
uint64_t GetTotalBytesSent()
bool GenerateSelectSet(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
void AcceptConnection(const ListenSocket &hListenSocket)
A Span is an object that can refer to a contiguous sequence of objects.
CClientUIInterface uiInterface
std::string GetNetworkName(enum Network net)
void MarkAddressGood(const CAddress &addr)
static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
boost::optional< T > Optional
Substitute for C++17 std::optional.
Information about a peer.
static CNetCleanup instance_of_cnetcleanup
std::vector< unsigned char > GetAddrBytes() const
bool SetSockAddr(const struct sockaddr *paddr)
std::thread threadSocketHandler
Simple class for background tasks that should be run periodically or once "after a while"...
We use block-relay-only connections to help prevent against partition attacks.
RecursiveMutex cs_totalBytesRecv
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
CConnman(uint64_t seed0, uint64_t seed1, bool network_active=true)
virtual void InitializeNode(CNode *pnode)=0
RecursiveMutex cs_addrLocal
bool IsManualConn() const
std::vector< CAddress > m_anchors
Addresses that were saved during the previous clean shutdown.
AddrFetch connections are short lived connections used to solicit addresses from peers.
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
int64_t GetTime()
Return system time (or mocked time, if set)
std::unique_ptr< CSemaphore > semAddnode
void Init(const Options &connOptions)
CThreadInterrupt interruptNet
static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
int GetRandInt(int nMax) noexcept
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
bool m_use_addrman_outgoing
std::vector< NetWhitebindPermissions > vWhiteBinds
std::atomic< int64_t > nLastBlockTime
UNIX epoch time of the last block received from this peer that we had not yet seen (e...
size_t SocketSendData(CNode *pnode) const
CHash256 & Write(Span< const unsigned char > input)
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
bool Read(CAddrMan &addr)
void AdvertiseLocal(CNode *pnode)
std::vector< AddedNodeInfo > GetAddedNodeInfo()
void AddSocketPermissionFlags(NetPermissionFlags &flags) const
const char *const ANCHORS_DATABASE_FILENAME
Anchor IP address database file name.
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
RecursiveMutex cs_hSocket
bool m_use_addrman_outgoing
Cache responses to addr requests to minimize privacy leak.
virtual bool ProcessMessages(CNode *pnode, std::atomic< bool > &interrupt)=0
int64_t nLastTry
last try whatsoever by us (memory only)
void RemoveLocal(const CService &addr)
bool IsLocal(const CService &addr)
check whether a given address is potentially local
std::atomic< std::chrono::microseconds > m_ping_start
When the last ping was sent, or 0 if no ping was ever sent.
RecursiveMutex cs_totalBytesSent
unsigned int nReceiveFloodSize
std::unique_ptr< TxRelay > m_tx_relay
void SplitHostPort(std::string in, int &portOut, std::string &hostOut)
void ThreadDNSAddressSeed()
static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
enum Network GetNetwork() const
Addresses from these networks are not publicly routable on the global Internet.