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>
54 const char*
const ANCHORS_DATABASE_FILENAME =
"anchors.dat";
57 static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL{15};
60 static constexpr
int DNSSEEDS_TO_QUERY_AT_ONCE = 3;
71 static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS{11};
72 static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS{5};
73 static constexpr
int DNSSEEDS_DELAY_PEER_THRESHOLD = 1000;
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
91 BF_EXPLICIT = (1U << 0),
92 BF_REPORT_ERROR = (1U << 1),
97 BF_DONT_ADVERTISE = (1U << 2),
102 static const uint64_t SELECT_TIMEOUT_MILLISECONDS = 50;
106 static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL;
107 static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL;
108 static const uint64_t RANDOMIZER_ID_ADDRCACHE = 0x1cf2e4ddd306dda9ULL;
116 std::map<CNetAddr, LocalServiceInfo> mapLocalHost
GUARDED_BY(cs_mapLocalHost);
123 m_addr_fetches.push_back(strDest);
138 int nBestReachability = -1;
140 LOCK(cs_mapLocalHost);
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);
193 static int GetnScore(
const CService& addr)
195 LOCK(cs_mapLocalHost);
196 if (mapLocalHost.count(addr) == 0)
return 0;
197 return mapLocalHost[addr].nScore;
250 LOCK(cs_mapLocalHost);
251 bool fAlready = mapLocalHost.count(addr) > 0;
253 if (!fAlready || nScore >= info.
nScore) {
254 info.
nScore = nScore + (fAlready ? 1 : 0);
269 LOCK(cs_mapLocalHost);
271 mapLocalHost.erase(addr);
278 LOCK(cs_mapLocalHost);
279 vfLimited[net] = !reachable;
284 LOCK(cs_mapLocalHost);
285 return !vfLimited[net];
297 LOCK(cs_mapLocalHost);
298 if (mapLocalHost.count(addr) == 0)
300 mapLocalHost[addr].nScore++;
309 LOCK(cs_mapLocalHost);
310 return mapLocalHost.count(addr) > 0;
316 for (
CNode* pnode : vNodes) {
317 if (static_cast<CNetAddr>(pnode->
addr) == ip) {
327 for (
CNode* pnode : vNodes) {
328 if (subNet.
Match(static_cast<CNetAddr>(pnode->
addr))) {
338 for (
CNode* pnode : vNodes) {
349 for (
CNode* pnode : vNodes) {
350 if (static_cast<CService>(pnode->
addr) == addr) {
365 for (
const CNode* pnode : vNodes) {
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;
480 CAddress addr_bind = GetBindAddress(hSocket);
517 return "outbound-full-relay";
519 return "block-relay-only";
534 if (addrName.empty()) {
535 addrName = addrNameIn;
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};
667 mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER)->second += out_err_raw_size;
673 mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(result->m_command);
674 if (i == mapRecvBytesPerMsgCmd.end())
675 i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
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;
821 pnode->nSendBytes += nBytes;
848 if (
it == pnode->vSendMsg.end()) {
852 pnode->vSendMsg.erase(pnode->vSendMsg.begin(),
it);
856 struct NodeEvictionCandidate
859 int64_t nTimeConnected;
860 int64_t nMinPingUsecTime;
861 int64_t nLastBlockTime;
863 bool fRelevantServices;
866 uint64_t nKeyedNetGroup;
871 static bool ReverseCompareNodeMinPingTime(
const NodeEvictionCandidate &a,
const NodeEvictionCandidate &b)
873 return a.nMinPingUsecTime > b.nMinPingUsecTime;
876 static bool ReverseCompareNodeTimeConnected(
const NodeEvictionCandidate &a,
const NodeEvictionCandidate &b)
878 return a.nTimeConnected > b.nTimeConnected;
881 static bool CompareLocalHostTimeConnected(
const NodeEvictionCandidate &a,
const NodeEvictionCandidate &b)
883 if (a.m_is_local != b.m_is_local)
return b.m_is_local;
884 return a.nTimeConnected > b.nTimeConnected;
887 static bool CompareNetGroupKeyed(
const NodeEvictionCandidate &a,
const NodeEvictionCandidate &b) {
888 return a.nKeyedNetGroup < b.nKeyedNetGroup;
891 static bool CompareNodeBlockTime(
const NodeEvictionCandidate &a,
const NodeEvictionCandidate &b)
894 if (a.nLastBlockTime != b.nLastBlockTime)
return a.nLastBlockTime < b.nLastBlockTime;
895 if (a.fRelevantServices != b.fRelevantServices)
return b.fRelevantServices;
896 return a.nTimeConnected > b.nTimeConnected;
899 static bool CompareNodeTXTime(
const NodeEvictionCandidate &a,
const NodeEvictionCandidate &b)
902 if (a.nLastTXTime != b.nLastTXTime)
return a.nLastTXTime < b.nLastTXTime;
903 if (a.fRelayTxes != b.fRelayTxes)
return b.fRelayTxes;
904 if (a.fBloomFilter != b.fBloomFilter)
return a.fBloomFilter;
905 return a.nTimeConnected > b.nTimeConnected;
909 static bool CompareNodeBlockRelayOnlyTime(
const NodeEvictionCandidate &a,
const NodeEvictionCandidate &b)
911 if (a.fRelayTxes != b.fRelayTxes)
return a.fRelayTxes;
912 if (a.nLastBlockTime != b.nLastBlockTime)
return a.nLastBlockTime < b.nLastBlockTime;
913 if (a.fRelevantServices != b.fRelevantServices)
return b.fRelevantServices;
914 return a.nTimeConnected > b.nTimeConnected;
918 template<
typename T,
typename Comparator>
919 static void EraseLastKElements(std::vector<T> &elements, Comparator comparator,
size_t k)
921 std::sort(elements.begin(), elements.end(), comparator);
922 size_t eraseSize = std::min(k, elements.size());
923 elements.erase(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;
954 NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->nMinPingUsecTime,
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);
967 EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
970 EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
973 EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
975 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeBlockRelayOnlyTime);
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());
981 EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
988 size_t initial_size = vEvictionCandidates.size();
989 size_t total_protect_size = initial_size / 2;
992 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareLocalHostTimeConnected);
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();
998 EraseLastKElements(vEvictionCandidates, ReverseCompareNodeTimeConnected, total_protect_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(),
1007 [](NodeEvictionCandidate
const &n){
return !n.prefer_evict;}),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;
1016 for (
const NodeEvictionCandidate &node : vEvictionCandidates) {
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) {
1044 struct sockaddr_storage sockaddr;
1045 socklen_t len =
sizeof(sockaddr);
1046 SOCKET hSocket = accept(hListenSocket.socket, (
struct sockaddr*)&sockaddr, &len);
1049 int nMaxInbound = nMaxConnections - m_max_outbound;
1052 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr)) {
1053 LogPrintf(
"Warning: Unknown socket family\n");
1058 hListenSocket.AddSocketPermissionFlags(permissionFlags);
1059 AddWhitelistPermissionFlags(permissionFlags, addr);
1060 bool legacyWhitelisted =
false;
1067 legacyWhitelisted =
true;
1072 for (
const CNode* pnode : vNodes) {
1085 if (!fNetworkActive) {
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());
1103 bool banned = m_banman && m_banman->IsBanned(addr);
1112 bool discouraged = m_banman && m_banman->IsDiscouraged(addr);
1120 if (nInbound >= nMaxInbound)
1122 if (!AttemptToEvictConnection()) {
1124 LogPrint(
BCLog::NET,
"failed to find an eviction candidate - connection dropped (full)\n");
1130 NodeId id = GetNewNodeId();
1131 uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(
id).Finalize();
1132 CAddress addr_bind = GetBindAddress(hSocket);
1139 const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
1140 CNode* pnode =
new CNode(
id, nodeServices, GetBestHeight(), hSocket, addr, CalculateKeyedNetGroup(addr), nonce, addr_bind,
"",
ConnectionType::INBOUND, inbound_onion);
1146 m_msgproc->InitializeNode(pnode);
1152 vNodes.push_back(pnode);
1164 if (!fNetworkActive) {
1166 for (
CNode* pnode : vNodes) {
1175 std::vector<CNode*> vNodesCopy = vNodes;
1176 for (
CNode* pnode : vNodesCopy)
1181 vNodes.erase(
remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1191 vNodesDisconnected.push_back(pnode);
1197 std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
1198 for (
CNode* pnode : vNodesDisconnectedCopy)
1202 bool fDelete =
false;
1210 vNodesDisconnected.remove(pnode);
1223 vNodesSize = vNodes.size();
1225 if(vNodesSize != nPrevNodeCount) {
1226 nPrevNodeCount = vNodesSize;
1228 clientInterface->NotifyNumConnectionsChanged(vNodesSize);
1267 for (
const ListenSocket& hListenSocket : vhListenSocket) {
1268 recv_set.insert(hListenSocket.socket);
1273 for (
CNode* pnode : vNodes)
1290 select_send = !pnode->vSendMsg.empty();
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;
1315 if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1316 interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
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));
1343 if (poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS) < 0)
return;
1345 if (interruptNet)
return;
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);
1354 void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1356 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1357 if (!GenerateSelectSet(recv_select_set, send_select_set, error_select_set)) {
1358 interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS));
1365 struct timeval timeout;
1367 timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000;
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);
1405 if (!interruptNet.sleep_for(std::chrono::milliseconds(SELECT_TIMEOUT_MILLISECONDS)))
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;
1432 SocketEvents(recv_set, send_set, error_set);
1434 if (interruptNet)
return;
1439 for (
const ListenSocket& hListenSocket : vhListenSocket)
1441 if (hListenSocket.socket !=
INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0)
1443 AcceptConnection(hListenSocket);
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;
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];
1485 nBytes = recv(pnode->hSocket, pchBuf,
sizeof(pchBuf),
MSG_DONTWAIT);
1489 bool notify =
false;
1492 RecordBytesRecv(nBytes);
1494 size_t nSizeAdded = 0;
1499 nSizeAdded +=
it->m_raw_message_size;
1503 pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->
vRecvMsg, pnode->
vRecvMsg.begin(),
it);
1507 WakeMessageHandler();
1510 else if (nBytes == 0)
1518 else if (nBytes < 0)
1538 size_t nBytes = SocketSendData(pnode);
1540 RecordBytesSent(nBytes);
1544 InactivityCheck(pnode);
1548 for (
CNode* pnode : vNodesCopy)
1555 while (!interruptNet)
1567 fMsgProcWake =
true;
1569 condMsgProc.notify_one();
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();
1698 }
else if (addrman.size() == 0) {
1702 seeds_right_now = seeds.size();
1717 const std::chrono::seconds seeds_wait_time = (addrman.size() >= DNSSEEDS_DELAY_PEER_THRESHOLD ? DNSSEEDS_DELAY_MANY_PEERS : DNSSEEDS_DELAY_FEW_PEERS);
1719 for (
const std::string& seed : seeds) {
1720 if (seeds_right_now == 0) {
1721 seeds_right_now += DNSSEEDS_TO_QUERY_AT_ONCE;
1723 if (addrman.size() > 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) {
1730 std::chrono::seconds w = std::min(DNSSEEDS_DELAY_FEW_PEERS, to_wait);
1731 if (!interruptNet.sleep_for(w))
return;
1737 for (
const CNode* pnode : vNodes) {
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");
1754 if (interruptNet)
return;
1757 if (!fNetworkActive) {
1758 LogPrintf(
"Waiting for network to be reactivated before querying DNS seeds.\n");
1760 if (!interruptNet.sleep_for(std::chrono::seconds{1}))
return;
1761 }
while (!fNetworkActive);
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);
1785 addrman.Add(vAdd, resolveSource);
1794 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1810 std::string strDest;
1812 LOCK(m_addr_fetches_mutex);
1813 if (m_addr_fetches.empty())
1815 strDest = m_addr_fetches.front();
1816 m_addr_fetches.pop_front();
1827 return m_try_another_outbound_peer;
1832 m_try_another_outbound_peer = flag;
1833 LogPrint(
BCLog::NET,
"net: setting try another outbound peer=%s\n", flag ?
"true" :
"false");
1847 for (
const CNode* pnode : vNodes) {
1853 return std::max(nOutbound - m_max_outbound_full_relay - m_max_outbound_block_relay, 0);
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++)
1870 if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1874 if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1884 while (!interruptNet)
1888 if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
1899 if (addrman.size() == 0 && (
GetTime() - nStart > 60)) {
1900 static bool done =
false;
1902 LogPrintf(
"Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1905 addrman.Add(convertSeed6(
Params().FixedSeeds()), local);
1916 int nOutboundFullRelay = 0;
1917 int nOutboundBlockRelay = 0;
1918 std::set<std::vector<unsigned char> > setConnected;
1922 for (
const CNode* pnode : vNodes) {
1939 setConnected.insert(pnode->
addr.
GetGroup(addrman.m_asmap));
1946 bool anchor =
false;
1947 bool fFeeler =
false;
1959 if (!m_anchors.empty() && (nOutboundBlockRelay < m_max_outbound_block_relay)) {
1962 }
else if (nOutboundFullRelay < m_max_outbound_full_relay) {
1964 }
else if (nOutboundBlockRelay < m_max_outbound_block_relay) {
1966 }
else if (GetTryNewOutboundPeer()) {
1968 }
else if (nTime > nNextFeeler) {
1977 addrman.ResolveCollisions();
1981 while (!interruptNet)
1983 if (anchor && !m_anchors.empty()) {
1984 const CAddress addr = m_anchors.back();
1985 m_anchors.pop_back();
1988 setConnected.count(addr.
GetGroup(addrman.m_asmap)))
continue;
2006 addr = addrman.SelectTriedCollision();
2011 addr = addrman.Select(
true);
2012 }
else if (AlreadyConnectedToAddress(addr)) {
2020 addr = addrman.Select(
true);
2024 addr = addrman.Select();
2028 if (!fFeeler && setConnected.count(addr.
GetGroup(addrman.m_asmap))) {
2041 if (nANow - addr.
nLastTry < 600 && nTries < 30)
2066 if (!interruptNet.sleep_for(std::chrono::milliseconds(randsleep)))
2071 OpenNetworkConnection(addrConnect, (
int)setConnected.size() >= std::min(nMaxConnections - 1, 2), &grant,
nullptr, conn_type);
2078 std::vector<CAddress> ret;
2080 for (
const CNode* pnode : vNodes) {
2082 ret.push_back(pnode->
addr);
2091 std::vector<AddedNodeInfo> ret;
2093 std::list<std::string> lAddresses(0);
2095 LOCK(cs_vAddedNodes);
2096 ret.reserve(vAddedNodes.size());
2097 std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
2102 std::map<CService, bool> mapConnected;
2103 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
2106 for (
const CNode* pnode : vNodes) {
2111 if (!addrName.empty()) {
2112 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->
IsInboundConn(),
static_cast<const CService&
>(pnode->
addr));
2117 for (
const std::string& strAddNode : lAddresses) {
2120 if (service.IsValid()) {
2122 auto it = mapConnected.find(service);
2123 if (
it != mapConnected.end()) {
2124 addedNode.resolvedAddress = service;
2125 addedNode.fConnected =
true;
2126 addedNode.fInbound =
it->second;
2130 auto it = mapConnectedByName.find(strAddNode);
2131 if (
it != mapConnectedByName.end()) {
2132 addedNode.resolvedAddress =
it->second.second;
2133 addedNode.fConnected =
true;
2134 addedNode.fInbound =
it->second.first;
2137 ret.emplace_back(std::move(addedNode));
2148 std::vector<AddedNodeInfo> vInfo = GetAddedNodeInfo();
2151 if (!info.fConnected) {
2152 if (!grant.TryAcquire()) {
2160 if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
2165 if (!interruptNet.sleep_for(std::chrono::seconds(tried ? 60 : 2)))
2181 if (!fNetworkActive) {
2185 bool banned_or_discouraged = m_banman && (m_banman->IsDiscouraged(addrConnect) || m_banman->IsBanned(addrConnect));
2186 if (
IsLocal(addrConnect) || banned_or_discouraged || AlreadyConnectedToAddress(addrConnect)) {
2189 }
else if (FindNode(std::string(pszDest)))
2192 CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
2199 m_msgproc->InitializeNode(pnode);
2202 vNodes.push_back(pnode);
2208 while (!flagInterruptMsgProc)
2210 std::vector<CNode*> vNodesCopy;
2213 vNodesCopy = vNodes;
2214 for (
CNode* pnode : vNodesCopy) {
2219 bool fMoreWork =
false;
2221 for (
CNode* pnode : vNodesCopy)
2227 bool fMoreNodeWork = m_msgproc->ProcessMessages(pnode, flagInterruptMsgProc);
2228 fMoreWork |= (fMoreNodeWork && !pnode->
fPauseSend);
2229 if (flagInterruptMsgProc)
2234 m_msgproc->SendMessages(pnode);
2237 if (flagInterruptMsgProc)
2243 for (
CNode* pnode : vNodesCopy)
2249 condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [
this]()
EXCLUSIVE_LOCKS_REQUIRED(mutexMsgProc) {
return fMsgProcWake; });
2251 fMsgProcWake =
false;
2260 struct sockaddr_storage sockaddr;
2261 socklen_t len =
sizeof(sockaddr);
2262 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len))
2279 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (
sockopt_arg_type)&nOne,
sizeof(
int));
2285 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
sockopt_arg_type)&nOne,
sizeof(
int));
2288 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2289 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (
const char*)&nProtLevel,
sizeof(
int));
2293 if (::bind(hListenSocket, (
struct sockaddr*)&sockaddr, len) ==
SOCKET_ERROR)
2315 vhListenSocket.push_back(ListenSocket(hListenSocket, permissions));
2326 char pszHostName[256] =
"";
2327 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR)
2329 std::vector<CNetAddr> vaddr;
2339 #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2341 struct ifaddrs* myaddrs;
2342 if (getifaddrs(&myaddrs) == 0)
2344 for (
struct ifaddrs* ifa = myaddrs; ifa !=
nullptr; ifa = ifa->ifa_next)
2346 if (ifa->ifa_addr ==
nullptr)
continue;
2347 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
2348 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
2349 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
2350 if (ifa->ifa_addr->sa_family == AF_INET)
2352 struct sockaddr_in* s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
2357 else if (ifa->ifa_addr->sa_family == AF_INET6)
2359 struct sockaddr_in6* s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
2365 freeifaddrs(myaddrs);
2372 LogPrintf(
"%s: %s\n", __func__, active);
2374 if (fNetworkActive == active) {
2378 fNetworkActive = active;
2380 uiInterface.NotifyNetworkActiveChanged(fNetworkActive);
2384 : nSeed0(nSeed0In), nSeed1(nSeed1In)
2386 SetTryNewOutboundPeer(
false);
2388 Options connOptions;
2390 SetNetworkActive(network_active);
2395 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2410 if (addr.
IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !(permissions &
PF_NOBAN)) {
2418 const std::vector<CService>& binds,
2419 const std::vector<NetWhitebindPermissions>& whiteBinds,
2420 const std::vector<CService>& onion_binds)
2422 bool fBound =
false;
2423 for (
const auto& addrBind : binds) {
2426 for (
const auto& addrBind : whiteBinds) {
2427 fBound |=
Bind(addrBind.m_service, (BF_EXPLICIT | BF_REPORT_ERROR), addrBind.m_flags);
2429 if (binds.empty() && whiteBinds.empty()) {
2430 struct in_addr inaddr_any;
2431 inaddr_any.s_addr = htonl(INADDR_ANY);
2432 struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2437 for (
const auto& addr_bind : onion_binds) {
2450 nTotalBytesRecv = 0;
2454 nTotalBytesSent = 0;
2455 nMaxOutboundTotalBytesSentInCycle = 0;
2456 nMaxOutboundCycleStartTime = 0;
2459 if (fListen && !
InitBinds(connOptions.vBinds, connOptions.vWhiteBinds, connOptions.onion_binds)) {
2462 _(
"Failed to listen on any port. Use -listen=0 if you want this."),
2468 for (
const auto& strDest : connOptions.vSeedNodes) {
2483 LogPrintf(
"Invalid or missing peers.dat; recreating\n");
2494 LogPrintf(
"%i block-relay-only anchors will be tried for connections.\n",
m_anchors.size());
2497 uiInterface.InitMessage(
_(
"Starting network threads...").translated);
2520 fMsgProcWake =
false;
2534 if (connOptions.m_use_addrman_outgoing && !connOptions.m_specified_outgoing.empty()) {
2537 _(
"Cannot provide specific connections and have addrman find outgoing connections at the same."),
2542 if (connOptions.m_use_addrman_outgoing || !connOptions.m_specified_outgoing.empty())
2567 static CNetCleanup instance_of_cnetcleanup;
2625 for (
CNode* pnode : vNodes)
2627 for (ListenSocket& hListenSocket : vhListenSocket)
2633 for (
CNode* pnode : vNodes) {
2640 vNodesDisconnected.clear();
2641 vhListenSocket.clear();
2649 bool fUpdateConnectionTime =
false;
2651 if (fUpdateConnectionTime) {
2675 return addrman.
Add(vAddr, addrFrom, nTimePenalty);
2680 std::vector<CAddress> addresses =
addrman.
GetAddr(max_addresses, max_pct);
2682 addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
2693 auto local_socket_bytes = GetBindAddress(socket).GetAddrBytes();
2696 .Write(local_socket_bytes.data(), local_socket_bytes.size())
2698 const auto current_time = GetTime<std::chrono::microseconds>();
2700 CachedAddrResponse& cache_entry = r.first->second;
2701 if (cache_entry.m_cache_entry_expiration < current_time) {
2702 cache_entry.m_addrs_response_cache =
GetAddresses(max_addresses, max_pct);
2727 cache_entry.m_cache_entry_expiration = current_time + std::chrono::hours(21) +
GetRandMillis(std::chrono::hours(6));
2729 return cache_entry.m_addrs_response_cache;
2735 for (
const std::string&
it : vAddedNodes) {
2736 if (strNode ==
it)
return false;
2739 vAddedNodes.push_back(strNode);
2746 for(std::vector<std::string>::iterator
it = vAddedNodes.begin();
it != vAddedNodes.end(); ++
it) {
2747 if (strNode == *
it) {
2748 vAddedNodes.erase(
it);
2759 return vNodes.size();
2762 for (
const auto& pnode : vNodes) {
2775 vstats.reserve(vNodes.size());
2776 for (
CNode* pnode : vNodes) {
2777 vstats.emplace_back();
2794 bool disconnected =
false;
2796 for (
CNode* pnode : vNodes) {
2799 disconnected =
true;
2802 return disconnected;
2813 for(
CNode* pnode : vNodes) {
2814 if (
id == pnode->
GetId()) {
2825 nTotalBytesRecv += bytes;
2831 nTotalBytesSent += bytes;
2834 if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe < now)
2837 nMaxOutboundCycleStartTime = now;
2838 nMaxOutboundTotalBytesSentInCycle = 0;
2842 nMaxOutboundTotalBytesSentInCycle += bytes;
2848 nMaxOutboundLimit = limit;
2854 return nMaxOutboundLimit;
2860 return nMaxOutboundTimeframe;
2866 if (nMaxOutboundLimit == 0)
2869 if (nMaxOutboundCycleStartTime == 0)
2870 return nMaxOutboundTimeframe;
2872 uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe;
2874 return (cycleEndTime < now) ? 0 : cycleEndTime -
GetTime();
2880 if (nMaxOutboundTimeframe != timeframe)
2884 nMaxOutboundCycleStartTime =
GetTime();
2886 nMaxOutboundTimeframe = timeframe;
2892 if (nMaxOutboundLimit == 0)
2895 if (historicalBlockServingLimit)
2900 if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
2903 else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
2912 if (nMaxOutboundLimit == 0)
2915 return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
2921 return nTotalBytesRecv;
2927 return nTotalBytesSent;
2937 nBestHeight.store(height, std::memory_order_release);
2942 return nBestHeight.load(std::memory_order_acquire);
2947 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)
2950 addrBind(addrBindIn),
2951 nKeyedNetGroup(nKeyedNetGroupIn),
2956 nLocalHostNonce(nLocalHostNonceIn),
2957 m_conn_type(conn_type_in),
2958 nLocalServices(nLocalServicesIn),
2959 nMyStartingHeight(nMyStartingHeightIn),
2960 m_inbound_onion(inbound_onion)
2962 hSocket = hSocketIn;
2963 addrName = addrNameIn ==
"" ? addr.ToStringIPPort() : addrNameIn;
2966 m_tx_relay = MakeUnique<TxRelay>();
2969 if (RelayAddrsWithConn()) {
2970 m_addr_known = MakeUnique<CRollingBloomFilter>(5000, 0.001);
2974 mapRecvBytesPerMsgCmd[msg] = 0;
2999 size_t nMessageSize = msg.
data.size();
3003 std::vector<unsigned char> serializedHeader;
3004 pnode->
m_serializer->prepareForTransport(msg, serializedHeader);
3005 size_t nTotalSize = nMessageSize + serializedHeader.size();
3007 size_t nBytesSent = 0;
3010 bool optimisticSend(pnode->vSendMsg.empty());
3018 pnode->vSendMsg.push_back(std::move(serializedHeader));
3020 pnode->vSendMsg.push_back(std::move(msg.
data));
3023 if (optimisticSend ==
true)
3032 CNode* found =
nullptr;
3034 for (
auto&& pnode : vNodes) {
3035 if(pnode->
GetId() == id) {
3056 return now + (int64_t)(log1p(
GetRand(1ULL << 48) * -0.0000000000000035527136788 ) * average_interval_seconds * -1000000.0 + 0.5);
std::atomic< bool > flagInterruptMsgProc
void copyStats(CNodeStats &stats, const std::vector< bool > &m_asmap)
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.
bool IsReachable(enum Network net)
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 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
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
uint64_t GetLocalNonce() const
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ServiceFlags
nServices flags
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.
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...
CNode * FindNode(const CNetAddr &ip)
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)
static bool NodeFullyConnected(const CNode *pnode)
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)
const std::string NET_MESSAGE_COMMAND_OTHER
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 SeenLocal(const CService &addr)
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool &complete)
mapMsgCmdSize mapSendBytesPerMsgCmd
std::string ToStringIP() const
int64_t count_microseconds(std::chrono::microseconds t)
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct)
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
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)
RecursiveMutex cs_vProcessMsg
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
void AdvertiseLocal(CNode *pnode)
void SetTryNewOutboundPeer(bool flag)
std::unique_ptr< TransportDeserializer > m_deserializer
void ThreadSocketHandler()
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
bool IsBlockOnlyConn() const
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()
std::list< CNetMessage > vRecvMsg
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)
RecursiveMutex cs_sendProcessing
ServiceFlags nLocalServices
Services this instance offers.
bool DisconnectNode(const std::string &node)
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.
const uint256 & GetMessageHash() const
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.
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)
void AddAddrFetch(const std::string &strDest)
bool GetLocal(CService &addr, const CNetAddr *paddrPeer=nullptr)
bool AddNode(const std::string &node)
std::condition_variable condMsgProc
bool IsFullOutboundConn() const
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)
RecursiveMutex m_addr_fetches_mutex
bool IsPeerAddrLocalGood(CNode *pnode)
bilingual_str _(const char *psz)
Translation function.
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
A combination of a network address (CNetAddr) and a (TCP) port.
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...
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)
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()
RecursiveMutex cs_mapLocalHost
std::string ToString() const
void SetNetworkActive(bool active)
#define WAIT_LOCK(cs, name)
const CMessageHeader::MessageStartChars & MessageStart() const
CClientUIInterface * clientInterface
void GetNodeStats(std::vector< CNodeStats > &vstats)
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
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()
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)
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
void RemoveLocal(const CService &addr)
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
#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
int GetBestHeight() const
std::thread threadOpenConnections
bool AttemptToEvictConnection()
ConnectionType
Different types of connections to a peer.
bool IsOutboundOrBlockRelayConn() const
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()
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
std::string ConnectionTypeAsString() const
void SetBestHeight(int height)
SOCKET CreateSocket(const CService &addrConnect)
Try to create a socket file descriptor with specific properties in the communications domain (address...
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.
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()
These are the default connections that we use to connect with the network.
std::atomic< int > nVersion
void InterruptSocks5(bool interrupt)
unsigned int nSendBufferMaxSize
static const bool DEFAULT_BLOCKSONLY
Default for blocks only.
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.
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
bool IsBanned(const CNetAddr &net_addr)
Return whether net_addr is banned.
std::string ToString() const
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.
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
CClientUIInterface uiInterface
std::string GetNetworkName(enum Network net)
void MarkAddressGood(const CAddress &addr)
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.
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
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
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)
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::atomic_bool fPauseRecv
std::unique_ptr< CSemaphore > semAddnode
void Init(const Options &connOptions)
CThreadInterrupt interruptNet
static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
int GetRandInt(int nMax) noexcept
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
bool AddLocal(const CService &addr, int nScore=LOCAL_NONE)
std::atomic< int64_t > nLastBlockTime
UNIX epoch time of the last block received from this peer that we had not yet seen (e...
bool IsLocal(const CService &addr)
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)
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
int64_t nLastTry
last try whatsoever by us (memory only)
std::vector< AddedNodeInfo > GetAddedNodeInfo()
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
Optional< CNetMessage > GetMessage(std::chrono::microseconds time, uint32_t &out_err_raw_size) override
std::unique_ptr< TxRelay > m_tx_relay
void SplitHostPort(std::string in, int &portOut, std::string &hostOut)
void ThreadDNSAddressSeed()
enum Network GetNetwork() const
Addresses from these networks are not publicly routable on the global Internet.